myawr布置

Posted magicaltravel

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了myawr布置相关的知识,希望对你有一定的参考价值。

实现功能:

类似于osw,收集mysql线程以及锁等待的状态,和osw不同的是,myawr是嵌入到mysql里面去的,要使用该功能,需要打开事件  set global event_scheduler = on;

 

其中收集日志的表使用自建分区,并且会自动drop掉7天以前的分区。

 

create database myawr DEFAULT CHARACTER SET utf8;

use myawr;

CREATE TABLE myawr.`processliststatus` (
  `ID` bigint(21) unsigned NOT NULL DEFAULT ‘0‘,
  `USER` varchar(32) NOT NULL DEFAULT ‘‘,
  `HOST` varchar(64) NOT NULL DEFAULT ‘‘,
  `DB` varchar(64) DEFAULT NULL,
  `COMMAND` varchar(16) NOT NULL DEFAULT ‘‘,
  `TIME` int(7) NOT NULL DEFAULT ‘0‘,
  `STATE` varchar(64) DEFAULT NULL,
  `INFO` longtext,
  `clock` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `snapid` bigint(20) DEFAULT NULL,
  KEY `idx_clock` (`clock`),
  key idx_snapid(snapid)
);

CREATE TABLE myawr.`mysqldumplog` (
  `ID` bigint(21) unsigned NOT NULL DEFAULT ‘0‘,
  `USER` varchar(32) NOT NULL DEFAULT ‘‘,
  `HOST` varchar(64) NOT NULL DEFAULT ‘‘,
  `DB` varchar(64) DEFAULT NULL,
  `COMMAND` varchar(16) NOT NULL DEFAULT ‘‘,
  `TIME` int(7) NOT NULL DEFAULT ‘0‘,
  `STATE` varchar(64) DEFAULT NULL,
  `INFO` longtext,
  `clock` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY `idx_clock` (`clock`)
);

CREATE TABLE myawr.`lockstatus` (
  `clock` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `wating_trx_state` varchar(255) DEFAULT NULL,
  `waiting_trx_id` bigint(20) DEFAULT NULL,
  `waiting_thread` int(11) DEFAULT NULL,
  `waiting_query` varchar(2000) DEFAULT NULL,
  `blocking_trx_state` varchar(255) DEFAULT NULL,
  `blocking_trx_id` bigint(20) DEFAULT NULL,
  `blocking_thread` int(11) DEFAULT NULL,
  `blocking_query` varchar(2000) DEFAULT NULL,
  `snapid` bigint(20) DEFAULT NULL,
  KEY `idx_clock` (`clock`),
  key idx_snapid(snapid)
);

DELIMITER $$
CREATE PROCEDURE myawr.`partition_verify`(SCHEMANAME VARCHAR(64), TABLENAME VARCHAR(64), HOURLYINTERVAL INT(11))
BEGIN
        DECLARE PARTITION_NAME VARCHAR(16);
        DECLARE RETROWS INT(11);
        DECLARE FUTURE_TIMESTAMP TIMESTAMP;

      
        SELECT COUNT(1) INTO RETROWS
        FROM information_schema.partitions
        WHERE table_schema = SCHEMANAME AND table_name = TABLENAME AND partition_name IS NULL;

     
        IF RETROWS = 1 THEN
             
                SET FUTURE_TIMESTAMP = TIMESTAMPADD(HOUR, HOURLYINTERVAL, CONCAT(CURDATE(), " ", ‘00:00:00‘));
                SET PARTITION_NAME = DATE_FORMAT(CURDATE(), ‘p%Y%m%d%H00‘);

                -- Create the partitioning query
                SET @__PARTITION_SQL = CONCAT("ALTER TABLE ", SCHEMANAME, ".", TABLENAME, " PARTITION BY RANGE(UNIX_TIMESTAMP(`clock`))");
                SET @__PARTITION_SQL = CONCAT(@__PARTITION_SQL, "(PARTITION ", PARTITION_NAME, " VALUES LESS THAN (", UNIX_TIMESTAMP(FUTURE_TIMESTAMP), "));");

                -- Run the partitioning query
                PREPARE STMT FROM @__PARTITION_SQL;
                EXECUTE STMT;
                DEALLOCATE PREPARE STMT;
        END IF;
END $$

CREATE PROCEDURE myawr.`partition_create` ( SCHEMANAME VARCHAR ( 64 ), TABLENAME VARCHAR ( 64 ), PARTITIONNAME VARCHAR ( 64 ), CLOCK INT ) BEGIN

DECLARE
	RETROWS INT;
SELECT
	COUNT( 1 ) INTO RETROWS 
FROM
	information_schema.PARTITIONS 
WHERE
	table_schema = SCHEMANAME 
	AND table_name = TABLENAME 
	AND partition_description >= CLOCK;
IF
	RETROWS = 0 THEN

SELECT
	CONCAT( "partition_create(", SCHEMANAME, ",", TABLENAME, ",", PARTITIONNAME, ",", CLOCK, ")" ) AS msg;

SET @SQL = CONCAT( ‘ALTER TABLE ‘, SCHEMANAME, ‘.‘, TABLENAME, ‘ ADD PARTITION (PARTITION ‘, PARTITIONNAME, ‘ VALUES LESS THAN (‘, CLOCK, ‘));‘ );
PREPARE STMT 
FROM
	@SQL;
EXECUTE STMT;
DEALLOCATE PREPARE STMT;

END IF;

END $$

CREATE PROCEDURE myawr.`partition_drop` ( SCHEMANAME VARCHAR ( 64 ), TABLENAME VARCHAR ( 64 ), DELETE_BELOW_PARTITION_DATE BIGINT ) BEGIN
DECLARE
	done INT DEFAULT FALSE;
DECLARE
	drop_part_name VARCHAR ( 16 );
DECLARE
	myCursor CURSOR FOR SELECT
	partition_name 
FROM
	information_schema.PARTITIONS 
WHERE
	table_schema = SCHEMANAME 
	AND table_name = TABLENAME 
	AND CAST( SUBSTRING( partition_name FROM 2 ) AS UNSIGNED ) < DELETE_BELOW_PARTITION_DATE;
DECLARE
	CONTINUE HANDLER FOR NOT FOUND 
	SET done = TRUE;
SET @alter_header = CONCAT( "ALTER TABLE ", SCHEMANAME, ".", TABLENAME, " DROP PARTITION " );
SET @drop_partitions = "";
OPEN myCursor;
read_loop :
LOOP
    FETCH myCursor INTO drop_part_name;
	IF
    done THEN
    LEAVE read_loop;
	END IF;
	SET @drop_partitions =
	IF
    ( @drop_partitions = "", drop_part_name, CONCAT( @drop_partitions, ",", drop_part_name ) );
END LOOP;
IF
	@drop_partitions != "" THEN
    SET @full_sql = CONCAT( @alter_header, @drop_partitions, ";" );
	PREPARE STMT 
	FROM
        @full_sql;
	EXECUTE STMT;
	DEALLOCATE PREPARE STMT;
	SELECT
    CONCAT( SCHEMANAME, ".", TABLENAME ) AS `table`,
        @drop_partitions AS `partitions_deleted`;
    ELSE 
	SELECT
    CONCAT( SCHEMANAME, ".", TABLENAME ) AS `table`,
    "N/A" AS `partitions_deleted`;
END IF;
END $$

CREATE PROCEDURE myawr.`partition_maintenance`(SCHEMA_NAME VARCHAR(32), TABLE_NAME VARCHAR(32), KEEP_DATA_DAYS INT, HOURLY_INTERVAL INT, CREATE_NEXT_INTERVALS INT)
BEGIN
        DECLARE OLDER_THAN_PARTITION_DATE VARCHAR(16);
        DECLARE PARTITION_NAME VARCHAR(16);
        DECLARE OLD_PARTITION_NAME VARCHAR(16);
        DECLARE LESS_THAN_TIMESTAMP INT;
        DECLARE CUR_TIME INT;

        CALL partition_verify(SCHEMA_NAME, TABLE_NAME, HOURLY_INTERVAL);
        SET CUR_TIME = UNIX_TIMESTAMP(DATE_FORMAT(NOW(), ‘%Y-%m-%d 00:00:00‘));

        SET @__interval = 1;
        create_loop: LOOP
                IF @__interval > CREATE_NEXT_INTERVALS THEN
                        LEAVE create_loop;
                END IF;

                SET LESS_THAN_TIMESTAMP = CUR_TIME + (HOURLY_INTERVAL * @__interval * 3600);
                SET PARTITION_NAME = FROM_UNIXTIME(CUR_TIME + HOURLY_INTERVAL * (@__interval - 1) * 3600, ‘p%Y%m%d%H00‘);
                IF(PARTITION_NAME != OLD_PARTITION_NAME) THEN
                        CALL partition_create(SCHEMA_NAME, TABLE_NAME, PARTITION_NAME, LESS_THAN_TIMESTAMP);
                END IF;
                SET @[email protected]__interval+1;
                SET OLD_PARTITION_NAME = PARTITION_NAME;
        END LOOP;

        SET OLDER_THAN_PARTITION_DATE=DATE_FORMAT(DATE_SUB(NOW(), INTERVAL KEEP_DATA_DAYS DAY), ‘%Y%m%d0000‘);
        CALL partition_drop(SCHEMA_NAME, TABLE_NAME, OLDER_THAN_PARTITION_DATE);

END$$

CREATE PROCEDURE myawr.proc_awr_killdump( )
BEGIN
declare dump_id INT default false;
DECLARE done INT DEFAULT FALSE;
DECLARE myCursor CURSOR FOR SELECT id FROM information_schema.PROCESSLIST WHERE INFO like ‘SELECT /*!40001 SQL_NO_CACHE */ * FROM%‘;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
SET @dump_id =‘‘;
OPEN myCursor;
read_loop :
LOOP
FETCH myCursor INTO dump_id;
IF
done THEN
LEAVE read_loop;
END IF;
insert into myawr.mysqldumplog(ID,USER,HOST,DB,COMMAND,TIME,STATE,INFO) select ID,USER,HOST,DB,COMMAND,TIME,STATE,INFO from information_schema.processlist where id=dump_id;
call mysql.rds_kill(dump_id);
END LOOP;
END
$$

CREATE procedure myawr.proc_awr_getstatus()
begin
declare insertSessionCount INT default 0; -- 声明insert会话的计数器  

set @ha=unix_timestamp(now());
-- 查看是否有insert 会话
select count(*) into insertSessionCount  from  information_schema.processlist where INFO like ‘insert into myawr.processliststatus%‘;

-- 如果之前存在未结束的insert会话,则本次不insert
IF  insertSessionCount <1   THEN  
-- 排除非活跃会话和系统会话,并做截断操作
insert into myawr.processliststatus(ID,USER,HOST,DB,COMMAND,TIME,STATE,INFO,snapid) select ID,USER,HOST,DB,COMMAND,TIME,STATE,substring(INFO,1,3000), @ha from information_schema.processlist  where COMMAND not in (‘Sleep‘,‘Daemon‘,‘Binlog Dump GTID‘) and INFO not like ‘insert into myawr.processliststatus%‘;   

END IF;  
 

insert into  myawr.lockstatus(wating_trx_state,waiting_trx_id,waiting_thread,waiting_query,blocking_trx_state,blocking_trx_id,blocking_thread,blocking_query,snapid) SELECT r.trx_state wating_trx_state,r.trx_id waiting_trx_id,r.trx_mysql_thread_Id waiting_thread,r.trx_query waiting_query,b.trx_state blocking_trx_state,b.trx_id blocking_trx_id,b.trx_mysql_thread_id blocking_thread,b.trx_query blocking_query,@ha FROM information_schema.innodb_lock_waits w INNER JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id INNER JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id;
end
$$

create event myawr.event_awr_resetpartition
ON SCHEDULE
every 1 day
on completion preserve
do
begin
call partition_maintenance(‘myawr‘,‘processliststatus‘,7,24,30);
call partition_maintenance(‘myawr‘,‘lockstatus‘,7,24,30);
end
$$

create procedure myawr.proc_awr_enable(proc_name varchar(64))
begin



if proc_name = ‘all‘ then

	select "抱歉,该参数现在还没能实现,敬请期待" as msg;
elseif proc_name = ‘killdump‘ then
	alter event event_awr_killdump enable;
	select "enable event_awr_killdump succeed ~" as msg;
elseif proc_name = ‘getmysqlstatus‘ then
	alter event event_awr_getMysqlStatus enable;
	select "enable event_awr_getMysqlStatus succeed ~" as msg;
else
	select "参量输入有误抑或没有布置awr脚本!" as msg;
end if;

end
$$

create procedure myawr.proc_awr_disable(proc_name varchar(64))
begin



if proc_name = ‘all‘ then
	
	select "抱歉,该参数现在还没能实现,敬请期待" as msg;
elseif proc_name = ‘killdump‘ then
	alter event event_awr_killdump disable;
	select "disable event_awr_killdump succeed ~" as msg;
elseif proc_name = ‘getmysqlstatus‘ then
	alter event event_awr_getMysqlStatus disable;
	select "disable event event_awr_getMysqlStatus succeed ~" as msg;
else
	select "参量输入有误抑或没有布置awr脚本!" as msg;
end if;

end
$$

CREATE PROCEDURE myawr.myawr_help()
BEGIN
	select    "
	1、实现功能:
	1.1、默认每10s会收集一次mysql的processlist状态和锁等待情况。
	1.2、默认每9s检查是否存在dump操作,如果存在将会kill线程,并且将此记录在mysqldump_log表中。
	2、更改参数:
	2.1、修改脚本收集或检查的频率
	 最小时间不应该小于7s,否则可能会对数据库性能产生影响。

	mysql> call proc_awr_changeint(‘killdump‘,5);

	2.2、启用或停止脚本部分功能

	mysql> call proc_awr_enable(‘all‘);
	mysql> call proc_awr_enable(‘killdump‘);
	mysql> call proc_awr_enable(‘getmysqlstatus‘);

	mysql> call proc_awr_disable(‘all‘);
	mysql> call proc_awr_disable(‘killdump‘);
	mysql> call proc_awr_disable(‘getmysqlstatus‘);

	3、dump操作:
	3.1、停止非法dump监控事件

	mysql> call proc_awr_disable(‘killdump‘);

	4.2、进行dump操作

	mysqldump --single-transaction ***

	3.3、恢复监控事件

	mysql> call proc_awr_enable(‘killdump‘);"  AS help_message;
end
$$

create event myawr.event_awr_getMysqlStatus
ON SCHEDULE
-- 每隔10秒运行
every 10 second
on completion preserve
do call proc_awr_getstatus();
$$

CREATE EVENT myawr.event_awr_killdump
ON SCHEDULE 
-- 每隔9秒运行
EVERY 9 SECOND 
ON COMPLETION PRESERVE
DO CALL proc_awr_killdump ();
$$

delimiter ;


###############分割线###############################
show variables like ‘event_scheduler‘;


set global event_scheduler = on;
call  myawr.proc_awr_enable(‘getmysqlstatus‘);
call  myawr.proc_awr_disable(‘killdump‘); -- 云上启用该功能


-- event_scheduler=1 #写入/etc/my.cnf

  

以上是关于myawr布置的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P1854 花店橱窗布置 分析+题解代码

作业第三周作业

花店橱窗布置问题(FLOWER)

以响应式方式布置图标

以编程方式在Word文档中布局图像

是否有关于如何布置全局描述符表条目的约定?