mysql和sql的区别 如何判断事件正在运行

如何在Mysql 中,跟踪正在运行的Sql语句?象在Sql Server中的事件探查器可以跟踪一样。
[问题点数:50分,结帖人a558638]
本版专家分:0
结帖率 88.68%
CSDN今日推荐
本版专家分:60239
2014年1月 荣获微软MVP称号
2007年10月 PHP大版内专家分月排行榜第一2007年12月 其他数据库开发大版内专家分月排行榜第一2007年10月 其他数据库开发大版内专家分月排行榜第一2007年9月 其他数据库开发大版内专家分月排行榜第一
2014年6月 其他数据库开发大版内专家分月排行榜第二2008年11月 其他数据库开发大版内专家分月排行榜第二2006年12月 PHP大版内专家分月排行榜第二2007年9月 PHP大版内专家分月排行榜第二2007年6月 PHP大版内专家分月排行榜第二2008年2月 其他数据库开发大版内专家分月排行榜第二2008年1月 其他数据库开发大版内专家分月排行榜第二2007年11月 其他数据库开发大版内专家分月排行榜第二
2014年9月 其他数据库开发大版内专家分月排行榜第三2006年11月 PHP大版内专家分月排行榜第三2008年4月 其他数据库开发大版内专家分月排行榜第三2008年3月 其他数据库开发大版内专家分月排行榜第三
本版专家分:0
本版专家分:148
本版专家分:0
本版专家分:150
本版专家分:60239
2014年1月 荣获微软MVP称号
2007年10月 PHP大版内专家分月排行榜第一2007年12月 其他数据库开发大版内专家分月排行榜第一2007年10月 其他数据库开发大版内专家分月排行榜第一2007年9月 其他数据库开发大版内专家分月排行榜第一
2014年6月 其他数据库开发大版内专家分月排行榜第二2008年11月 其他数据库开发大版内专家分月排行榜第二2006年12月 PHP大版内专家分月排行榜第二2007年9月 PHP大版内专家分月排行榜第二2007年6月 PHP大版内专家分月排行榜第二2008年2月 其他数据库开发大版内专家分月排行榜第二2008年1月 其他数据库开发大版内专家分月排行榜第二2007年11月 其他数据库开发大版内专家分月排行榜第二
2014年9月 其他数据库开发大版内专家分月排行榜第三2006年11月 PHP大版内专家分月排行榜第三2008年4月 其他数据库开发大版内专家分月排行榜第三2008年3月 其他数据库开发大版内专家分月排行榜第三
本版专家分:255
匿名用户不能发表回复!|
其他相关推荐存储过程和事件总结 - 简书
存储过程和事件总结
任务需求:定时执行的任务,调用存储过程,进行数据迁移。存储过程相关总结:(存储过程的创建
不能伴随有if exists
需要提前判断删除同名的存储过程)存储过程的查看:select name from mysql.proc where db = your_db_name and type = PROCEDUREs查看存储过程或函数的创建代码show create procedure proc_存储过程的创建 语法以及遇到的问题MySQL中,创建存储过程的基本形式如下:CREATE PROCEDURE sp_name ([proc_parameter[,...]])[characteristic ...] routine_body其中,sp_name参数是存储过程的名称;proc_parameter表示存储过程的参数列表; characteristic参数指定存储过程的特性;routine_body参数是SQL代码的内容,可以用BEGIN…END来标志SQL代码的开始和结束。proc_parameter中的每个参数由3部分组成。这3部分分别是输入输出类型、参数名称和参数类型。其形式如下:[ IN | OUT | INOUT ] param_name type其中,IN表示输入参数;OUT表示输出参数; INOUT表示既可以是输入,也可以是输出; param_name参数是存储过程的参数名称;type参数指定存储过程的参数类型,该类型可以是MySQL数据库的任意数据类型。characteristic参数有多个取值。其取值说明如下:LANGUAGE SQL:说明routine_body部分是由SQL语言的语句组成,这也是数据库系统默认的语言。[NOT] DETERMINISTIC:指明存储过程的执行结果是否是确定的。DETERMINISTIC表示结果是确定的。每次执行存储过程时,相同的输入会得到相同的输出。NOT DETERMINISTIC表示结果是非确定的,相同的输入可能得到不同的输出。默认情况下,结果是非确定的。{ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }:指明子程序使用SQL语句的限制。CONTAINS SQL表示子程序包含SQL语句,但不包含读或写数据的语句;NO SQL表示子程序中不包含SQL语句;READS SQL DATA表示子程序中包含读数据的语句;MODIFIES SQL DATA表示子程序中包含写数据的语句。默认情况下,系统会指定为CONTAINS SQL。SQL SECURITY { DEFINER | INVOKER }:指明谁有权限来执行。DEFINER表示只有定义者自己才能够执行;INVOKER表示调用者可以执行。默认情况下,系统指定的权限是DEFINER。COMMENT 'string':注释信息。技巧:创建存储过程时,系统默认指定CONTAINS SQL,表示存储过程中使用了SQL语句。但是,如果存储过程中没有使用SQL语句,最好设置为NO SQL。而且,存储过程中最好在COMMENT部分对存储过程进行简单的注释,以便以后在阅读存储过程的代码时更加方便。创建一个名为num_from_employee的存储过程。代码如下:CREATE
num_from_employee (IN emp_id INT, OUT count_num INT )READS SQL DATABEGINSELECT
count_numFROM
employeeWHERE
d_id=emp_END上述代码中,存储过程名称为num_from_employee;输入变量为emp_id;输出变量为count_num。SELECT语句从employee表查询d_id值等于emp_id的记录,并用COUNT(*)计算d_id值相同的记录的条数,最后将计算结果存入count_num中。代码的执行结果如下:mysql& DELIMITER &&mysql& CREATE
num_from_employee(IN emp_id INT, OUT count_num INT )-& READS SQL DATA-& BEGIN-& SELECT
count_num-& FROM
employee-& WHERE
d_id=emp_-& END &&Query OK, 0 rows affected (0.09 sec)mysql& DELIMITER ;代码执行完毕后,没有报出任何出错信息就表示存储函数已经创建成功。以后就可以调用这个存储过程,数据库中会执行存储过程中的SQL语句。说明:MySQL中默认的语句结束符为分号(;)。存储过程中的SQL语句需要分号来
结束。为了避免冲突,首先用"DELIMITER &&"将MySQL的结束符设置为&&。最后再用"DELIMITER ;"来将结束符恢复成分号。这与创建触发器时是一样的。一、MySQL 创建存储过程“pr_add” 是个简单的 MySQL 存储过程,这个存储过程有两个 int 类型的输入参数 “a”、“b”,返回这两个参数的和。drop procedure if exists pr_-- 计算两个数之和create procedure pr_add(a int,b int)beginif a is null thenset a = 0;if b is null thenset b = 0;set c = a +/*- 不能在 MySQL 存储过程中使用。return 只能出现在函数中。/二、调用Mysql存储过程eg: call pr_add(10,20);执行 MySQL 存储过程,存储过程参数为 MySQL 用户变量。set @a = 10;set @b = 20;call pr_add(@a, @b);假定存储过程如下:create procedure pr_return2Pr(a int,out b int,inout c int) begin set b =a; set c = a+ endset @cc = 3;call pr_return2Pr(1,@bb,@cc);select @bb,@ 返回1,4如果存储过程中变量定义为out,可以不进行变量值定义,直接声明即可。inout
则需要提前set 变量,然后调用。IN为默认类型,值必须在调用时指定,值不能返回(值传递)OUT值可以返回(指针传递)INOUT值必须在调用时指定,值可以返回使用DECLARE来声明,DEFAULT赋默认值,SET赋值DECLARE counter INT DEFAULT 0;
- 默认为0SET counter = counter+1;
- 自增+1三、MySQL 存储过程特点创建 MySQL 存储过程的简单语法为:create procedure 存储过程名字()([in|out|inout] 参数 datatype)beginMySQL 语句;MySQL 存储过程参数如果不显式指定“in”、“out”、“inout”,则默认为“in”。习惯上,对于是“in” 的参数,我们都不会显式指定。如下,给出解释1. MySQL 存储过程名字后面的“()”是必须的,即使没有一个参数,也需要“()”2. MySQL 存储过程参数,不能在参数名称前加“@”,如:“@a int”。下面的创建存储过程语法在 MySQL 中是错误的(在 SQL Server 中是正确的)。 MySQL 存储过程中的变量,不需要在变量名字前加“@”,虽然 MySQL 客户端用户变量要加个“@”。create procedure pr_add(@a int,- 错误b int
- 正确)3. MySQL 存储过程的参数不能指定默认值。4. MySQL 存储过程不需要在 procedure body 前面加 “as”。而 SQL Server 存储过程必须加 “as” 关键字。create procedure pr_add(a int,b int)as
- 错误,MySQL 不需要 “as”beginmysql statement ...;5. 如果 MySQL 存储过程中包含单条或者多条 MySQL 语句,都需要 begin end 关键字。create procedure pr_add(a int,b int)beginmysql statement 1 ...;mysql statement 2 ...;6.MySQL 存储过程中的每条语句的末尾,都要加上分号 “;”...if a is null thenset a = 0;...7. MySQL 存储过程中的注释。/*这是个多行 MySQL 注释。/
- 这是单行 MySQL 注释 (注意- 后至少要有一个空格)if a is null then 这也是个单行 MySQL 注释set a = 0;...8. 不能在 MySQL 存储过程中使用 “return” 关键字。set c = a +/*- 不能在 MySQL 存储过程中使用。return 只能出现在函数中。/9. 调用 MySQL 存储过程时候,需要在过程名字后面加“()”,即使没有一个参数,也需要“()”call pr_no_param();10. 因为 MySQL 存储过程参数没有默认值,所以在调用 MySQL 存储过程时候,不能省略参数。可以用 null 来替代。call pr_add(10, null);mysql写条件判断时,注意时if
其中elseif之间是不能够有空格的。命令行编写存储过程命令是一定注意提前delimiter。说明:MySQL中默认的语句结束符为分号(;)。存储过程中的SQL语句需要分号来
结束。为了避免冲突,首先用"DELIMITER &&"将MySQL的结束符设置为&&。最后再用"DELIMITER ;"来将结束符恢复成分号。这与创建触发器时是一样的。但是mysql 窗口就没问题了。存储过程的删除: 不能在一个存储过程中删除另一个存储过程,只能调用另一个存储过程drop procedure if exists prName11,存储方法存储方法与存储过程的区别1,存储方法的参数列表只允许IN类型的参数,而且没必要也不允许指定IN关键字2,存储方法返回一个单一的值,值的类型在存储方法的头部定义3,存储方法可以在SQL语句内部调用4,存储方法不能返回结果集mysql事件:创建存储过程的时候,如果采用命令行的方式,需要先修改命令结束符,将分号改成其他的符号,注意delimiter时 不能在$$后添加;
否则就以$$;
作为结束标记了。-- 设置分隔符为 '$$' ,mysql默认的语句分隔符为 ';' ,这样在后续的 create 到 end 这段代码都会看成是一条语句来执行DELIMITER $$//创建存储过程或者事件语句//结束$$- 将语句分割符设置回 ';'DELIMITER ;事件简介事件(event)是MySQL在相应的时刻调用的过程式数据库对象。一个事件可调用一次,也可周期性的启动,它由一个特定的线程来管理的,也就是所谓的“事件调度器”。事件和触发器类似,都是在某些事情发生的时候启动。当数据库上启动一条语句的时候,触发器就启动了,而事件是根据调度事件来启动的。由于他们彼此相似,所以事件也称为临时性触发器。事件取代了原先只能由操作系统的计划任务来执行的工作,而且MySQL的事件调度器可以精确到每秒钟执行一个任务,而操作系统的计划任务(如:Linux下的CRON或Windows下的任务计划)只能精确到每分钟执行一次。2 事件的优缺点2.1 优点一些对数据定时性操作不再依赖外部程序,而直接使用数据库本身提供的功能。可以实现每秒钟执行一个任务,这在一些对实时性要求较高的环境下就非常实用了。2.2 缺点定时触发,不可以调用。3 创建事件一条create event语句创建一个事件。每个事件由两个主要部分组成,第一部分是事件调度(event schedule),表示事件何时启动以及按什么频率启动,第二部分是事件动作(event action ),这是事件启动时执行的代码,事件的动作包含一条SQL语句,它可能是一个简单地insert或者update语句,也可以使一个存储过程或者benin...end语句块,这两种情况允许我们执行多条SQL。一个事件可以是活动(打开)的或停止(关闭)的,活动意味着事件调度器检查事件动作是否必须调用,停止意味着事件的声明存储在目录中,但调度器不会检查它是否应该调用。在一个事件创建之后,它立即变为活动的,一个活动的事件可以执行一次或者多次。3.1 创建语法如下CREATE[DEFINER = { user | CURRENT_USER }]EVENT[IF NOT EXISTS]event_nameON SCHEDULE schedule[ON COMPLETION [NOT] PRESERVE][ENABLE | DISABLE | DISABLE ON SLAVE][COMMENT 'comment']DO event_schedule:AT timestamp [+ INTERVAL interval] ...| EVERY interval[STARTS timestamp [+ INTERVAL interval] ...][ENDS timestamp [+ INTERVAL interval] ...]interval:quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}名词解释:event_name :创建的event名字(唯一确定的)。ON SCHEDULE:计划任务。schedule: 决定event的执行时间和频率(注意时间一定要是将来的时间,过去的时间会出错),有两种形式 AT和EVERY。[ON COMPLETION [NOT] PRESERVE]: 可选项,默认是ON COMPLETION NOT PRESERVE 即计划任务执行完毕后自动drop该事件;ON COMPLETION
PRESERVE则不会drop掉。[COMMENT 'comment'] :可选项,comment 用来描述event;相当注释,最大长度64个字节。[ENABLE | DISABLE] :设定event的状态,默认ENABLE:表示系统尝试执行这个事件, DISABLE:关闭该事情,可以用alter修改DO event_body: 需要执行的sql语句(可以是复合语句)。CREATE EVENT在存储过程中使用时合法的。定时器 -- 创建定时器后会在mysql 中创建一个线程用以执行该事件。 user就是event_scheduler command-daemon state-waiting for next activation1.查看定时器-事件调度器 MySQL事件调度器event_scheduler负责调用事件,它默认是关闭的。这个调度器不断地监视一个事件是否要调用, 要创建事件,必须打开调度器。show variables like '%event_scheduler%';2.开启时间调度器命令行:SET GLOBAL event_scheduler = ON;SET @@global.event_scheduler = ON;SET GLOBAL event_scheduler = 1;SET @@global.event_scheduler = 1;配置文件:event_scheduler = 1 #或者ON查看调度器线程mysql&+----+-----------------+-----------+------+---------+------+------------------------+------------------+| Id | User
| Command | Time | State
|+----+-----------------+-----------+------+---------+------+------------------------+------------------+|
| localhost | NULL | Query
| show processlist ||
3 | event_scheduler | localhost | NULL | Daemon
6 | Waiting on empty queue | NULL
|+----+-----------------+-----------+------+---------+------+------------------------+------------------+关闭事件调度器通过命令行可通过如下任何一个命令行SET GLOBAL event_scheduler = OFF;SET @@global.event_scheduler = OFF;SET GLOBAL event_scheduler = 0;SET @@global.event_scheduler = 0;通过配置文件my.cnf在[mysqld]下增加event_scheduler = 0 #或者OFF,DISABLED查看调度器线程mysql&+----+------+-----------+------+---------+------+-------+------------------+| Id | User | Host
| Command | Time | State | Info
|+----+------+-----------+------+---------+------+-------+------------------+|
2 | root | localhost | NULL | Query
| show processlist |+----+------+-----------+------+---------+------+-------+------------------+查看事件运行状态:(1)查询mysql.event表;(2)通过SHOW EVENTS命令;(4)通过查询information_schema.events表(5)SHOW CREATE EVENT。 -- 查看创建目录总之,event的使用频率较低建议使用root用户进行创建和维护。使用权限单独使用event调用SQL语句时,查看和创建需要用户具有event权限,调用该SQL语句时,需要用户具有执行该SQL的权限。Event权限的设置保存在mysql.user表和mysql.db表的Event_priv字段中。当event和procedure配合使用的时候,查看和创建存储过程需要用户具有create routine权限,调用存储过程执行时需要使用excute权限,存储过程调用具体的SQL语句时,需要用户具有执行该SQL的权限。关于事件计划的权限:单独使用event调用SQL语句时,查看和创建需要用户具有event权限,调用该SQL语句时,需要用户具有执行该SQL的权限。Event权限的设置保存在mysql.user表和mysql.db表的Event_priv字段中。(FLUSH PRIVILEGES;)当event和procedure配合使用的时候,查看和创建存储过程需要用户具有create routine权限,调用存储过程执行时需要使用excute权限,存储过程调用具体的SQL语句时,需要用户具有执行该SQL的权限。SELECT HOST,USER,Event_priv FROM mysql.(Figure1:user表的Event_priv权限)获取当前登陆的用户和数据库:SELECT CURRENT_USER(), SCHEMA();从Figure1可以知道bfsql@%是没有Event_priv权限的,在该用户下创建事件的时候会出现下面的错误:Error Code: 1044Access denied for user 'bfsql'@'%' to database 'blog'如果出现上面的错误,执行下面的SQL就可以给bfsql@%赋予创建Event的权限:UPDATE mysql.user SET Event_priv = 'Y' WHERE HOST='%' AND USER='bfsql';如果你这个时候再次执行创建Event的SQL,还是会出现上面的错误,因为你需要执行:FLUSH PRIVILEGES;最后,你可以通过SHOW GRANTS FOR 'bfsql'@'%';查看所有权限;创建event语句相关命令解释:ON SCHEDULE 计划任务,有两种设定计划任务的方式:1. AT 时间戳,用来完成单次的计划任务。2. EVERY 时间(单位)的数量时间单位[STARTS 时间戳] [ENDS时间戳],用来完成重复的计划任务。在两种计划任务中,时间戳可以是任意的TIMESTAMP 和DATETIME 数据类型,时间戳需要大于当前时间。在重复的计划任务中,时间(单位)的数量可以是任意非空(Not Null)的整数式,时间单位是关键词:YEAR,MONTH,DAY,HOUR,MINUTE 或者SECOND。提示: 其他的时间单位也是合法的如:QUARTER, WEEK, YEAR_MONTH,DAY_HOUR,DAY_MINUTE,DAY_SECOND,HOUR_MINUTE,HOUR_SECOND, MINUTE_SECOND,不建议使用这些不标准的时间单位。标注4: [ON COMPLETION [NOT] PRESERVE]ON COMPLETION参数表示"当这个事件不会再发生的时候",即当单次计划任务执行完毕后或当重复性的计划任务执行到了ENDS阶段。而PRESERVE的作用是使事件在执行完毕后不会被Drop掉,建议使用该参数,以便于查看EVENT具体信息。标注5:[ENABLE | DISABLE]参数Enable和Disable表示设定事件的状态。Enable表示系统将执行这个事件。Disable表示系统不执行该事件。可以用如下命令关闭或开启事件:ALTER EVENT event_name
ENABLE/DISABLE标注6:[COMMENT 'comment']注释会出现在元数据中,它存储在information_schema表的COMMENT列,最大长度为64个字节。'comment'表示将注释内容放在单引号之间,建议使用注释以表达更全面的信息。当然SQL语句是有限制的,对它的限制跟函数Function和触发器Trigger 中对SQL语句的限制是一样的,如果你在函数Function 和触发器Trigger 中不能使用某些SQL,同样的在EVENT中也不能使用。明确的来说有下面几个:LOCK TABLESUNLOCK TABLESCREATE EVENTALTER EVENTLOAD DATA修改事件 使用ALTER EVENT 来修改事件,具体的ALTER语法如下,与创建事件的语法类似:删除事件:EVENT使用DROP EVENT语句来删除已经创建的事件,语法如下:DROP EVENT [IF EXISTS] event_name但当一个事件正在运行中时,删除该事件不会导致事件停止,事件会执行到完毕为止。使用DROP USER和DROP DATABASE 语句同时会将包含其中的事件删除。每隔一秒自动调用e_test()存储过程:CREATE EVENT IF NOT EXISTS e_testON SCHEDULE EVERY 1 SECONDON COMPLETION PRESERVEDO CALL e_test();每个月的一号凌晨1 点执行STAT()存储过程:CREATE
NOT EXISTS
STARTS DATE_ADD(DATE_ADD(DATE_SUB(CURDATE(),INTERVAL DAY(CURDATE())-1 DAY), INTERVAL 1 MONTH),INTERVAL 1 HOUR)ON
COMPLETION
ENABLEDOBEGINCALL STAT();END创建一个每隔3秒往test表中插入一条数据的事件,代码如下:CREATE EVENT IF NOT EXISTS test ON SCHEDULE EVERY 3 SECONDON COMPLETION PRESERVEDO INSERT INTO test(id,t1) VALUES('',NOW());创建一个10分钟后清空test表数据的事件CREATE EVENT IF NOT EXISTS testON SCHEDULEAT CURRENT_TIMESTAMP + INTERVAL 10 MINUTEDO TRUNCATE TABLE test.创建一个在 00:00:00时刻清空test表数据的事件CREATE EVENT IF NOT EXISTS testON SCHEDULEAT TIMESTAMP ' 00:00:00'DO TRUNCATE TABLE创建一个从日21点45分开始到10分钟后结束,运行每隔3秒往test表中插入一条数据的事件CREATE EVENT IF NOT EXISTS test ON SCHEDULE EVERY 3 SECONDSTARTS ' 21:49:00'ENDS ' 21:49:00'+ INTERVAL
10 MINUTEON COMPLETION PRESERVEDO INSERT INTO test(id,t1) VALUES('',NOW());注意:默认创建事件存储在当前库中,也可显示指定事件创建在哪个库中通过show events只能查看当前库中创建的事件事件执行完即释放,如立即执行事件,执行完后,事件便自动删除,多次调用事件或等待执行事件可以查看到。如果两个事件需要在同一时刻调用,mysql会确定调用他们的顺序,如果要指定顺序,需要确保一个事件至少在另一个事件1秒后执行对于递归调度的事件,结束日期不能在开始日期之前。select可以包含在一个事件中,然而他的结果消失了,就好像没执行过。删除事件:drop event 语句删除它。使用这条语句我们不需要等到最后一次事件调用。DROP EVENT [IF EXISTS] event_name,drop event if exists event_一个事件示例:每分钟的零秒执行数据迁移create event updateEachMinuteAt0Secondon schedule every 1 minute starts timestampadd(second,60 -second(current_timestamp()),current_timestamp())on completion preserve enabledobegincall updatetestevent();end函数体内使用函数变量提前声明
判断是否为空
条件块: e
当一个大型系统在建立时,会发现,很多的SQL操作是有重叠的,个别计算是相同的,比如:业务系统中,计算一张工单的计算方式。当遇到这些情况时,我们运用存储过程就是一个非常棒的优化啦。 本系列:demo下载 (一)MySQL优化笔记(一)--库与表基本操作以及数据增删改 (二)M...
1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语法,集合的语法,io的语法,虚拟机方面的语法。 1、一个&.java&源文件中是否可以包括多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个publ...
百战程序员_ Java1573题 QQ群:034603 掌握80%年薪20万掌握50%年薪10万 全程项目穿插, 从易到难,含17个项目视频和资料持续更新,请关注www.itbaizhan.com 国内最牛七星级团队马士兵、高淇等11位十年开发经验专...
5 步优化 MongoDB 以及其它数据库 - 后端 - 掘金原文链接 Jared Rosoff 在 Scale Out Camp 发表了一篇简洁、有效、有趣和令人信服的《8 分钟 MongoDB 教程》描述了如何进行 MongoDB 优化。 文中的方法不仅限于 Mongo...
转载自这里 存储过程简介 我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执...
定义函数的方式有两种:一种是函数声明,另一种是函数表达式。函数声明的语法是这样的。 说明:Firefox、Safari、Chrome和Opera都给函数定义了一个非标准的name属性,通过这个属性可以访问到给定函数指定的名字。 关于函数声明,它的一个重要特征就是函数声明提升...
(1) 昨天晚间忽然偏头痛发作。许是着了凉,也可能是拿手机看书刺激了眼神经。以前办公室内空气不流通时也会引发。总之这头痛病时不常会光顾一次,一犯病就做什么都不得劲,看什么都不顺眼。 早早上床去睡。按惯例如果沉沉睡上一觉后就会恢复如常。但是一直到半夜仍然觉得似醒非醒,晃晃脑袋...
就在日,我开始了人生第一次恋爱,在同年日,我亲手了结了这段初恋。 历时6个月不算轰轰烈烈的初恋就这样被我亲手掐断。不要问我为什么要这样,不要问我为什么不挽留,说分手的那个伤心难过也不比被分手的少。 回顾往昔和他在一起的一点一滴,都让我曾心...
下载MySql: http://dev.mysql.com/downloads/第一步 将压缩包解压到想要的目录(E:\cme) 配置环境变量 初始化,在bin文件下打开命令行(以管理员身份运行),输入 安装服务,在bin下运行 配置ini文件,打开E:\cme\mysql...MySQL复制事件在主备之间来回传输检测
来源:博客
 作者: 风一 编辑:
&&&&&&&&【IT168&技术】背景知识:  MySQL复制双主结构:主备之间可以互相复制,备库read_only被打开:  MySQL1(read/write)&&&MySQL2(read only)  双主结构的好处:当主库MySQL1 down掉之后,备库MySQL2关闭read_only后可以马上成为主库,而在MySQL1以read_only形式重新启动后,整个结构与原来一样,只是MySQL1和MySQL2互换了角色,因此MySQL2一开始就是一个standby(当然也能提供读的服务,分担MySQL1的部分查询压力)  线上问题:  复制结构:MySQL1 &&(dual master) && MySQL2 &(rep)&& MySQL3  MySQL1和MySQL2是双主结构,MySQL3是纯备库(需要时也可以与MySQL2互为双主)当MySQL1宕机而做主备切换时,MySQL2成为新主,期望MySQL1重启后成为standby的新备(即MySQL1和MySQL2的角色互换),MySQL3则保持不变。在MySQL1硬件失效导致重启不成功后,将MySQL3变成MySQL2的stand-by主库时,原先复制到MySQL2的复制事件会在MySQL2/3之间来回传输,导致严重问题:若插入数据上定义了主键或者唯一索引,主备上会不断报错:duplicate key,否则,主备上同一条记录会被不断插入!  经过分析最终找到了问题的原因,是由于server_id引起的,把上述复制构架进行简化可以很容易的重现事故  事故重现:<span style="color: #、配置server1和server2为双主结构:&&&&server1(server_id=<span style="color: #)&&&&(dual master)&& server2(server_id=<span style="color: #)<span style="color: #、在server1执行以下SQL命令:&& mysql& create table test.t1(id int);&& mysql& stop slave;&& mysql& insert into t1 values(<span style="color: #);&& mysql& set global server_id=<span style="color: #;&& mysql& start slave;<span style="color: #、在server1,server2上执行:&& mysql& select count(*) from t1;  分析:  从简化的例子中可以发现,导致复制事件的主要原因是server1的server_id发生了改变,原理如下:  在双主复制中,主库库更新数据时,会将更新事件发送到备库,备库更新数据、写binlog后,还会把复制事件发送给主库,因此最初主库上的更新事件又传了回来,这时候就要对复制事件进行判断,否则这种更新将在主备之间无线循环,判断依据就是server_id,因此当主库发现复制事件的server_id和自己的server_id相同时,放弃执行,于是主备之间可以正常复制了,但前提是主备的server_id保持不变  因此,对于上述简化结构,server1上插入一条记录一条记录之前stop slave,保证了插入查找在server2上执行后不能传到server1,在这之间server1的server_id发生了改变,当它start slave后,server2的复制事件被接收,由于server1此时的server_id为3,与复制事件中server_id(=1)不同,于是执行更新并写binlog,之后又将复制事件传递给server2,server2的server_id为2,也与复制事件中server_id(=1)不同,于是复制事件会在server_1和server_2之间循环传递和执行,停止这种传递的方法是将server1的server_id改回1  现在,线上事故也就不难解释了,MySQL1发送给MySQL2的复制事件,由于其server_id与MySQL2和MySQL3都不一样,当MySQL2与MySQL3互为双主后,复制事件会在它们之间循环传递和执行,让MySQL3的server_id变为MySQL1原来的server_id即可解决此问题(其实,这时MySQL3充当的就是MySQL1最初的角色)  此类问题一旦发生,大部分情况让MySQL主备表现异常,而少数情况会非常隐蔽,而如果没能及时发现并解决问题,数据就悲剧了&  因此,在到问题的真正原因后,我们尝试监测此问题,要想彻底杜绝不太可能,MySQL3自动判断它将要充当MySQL1的角色?  解决方案:  线上部署的MySQL节点拓扑结构有个明显特征:绝多数的1主1备,以及个别的1主多备,针对这些拓扑结构,处理此问题就可以简化许多,在备库复制的IO线程接收到主库发送的事件做如下判断:  1 事件的server_id与本实例的server_id不相同  2 事件的srever_id与当前实例的所有备库的server_id均不同  3 当前实例的master的也是其slave  其中:条件1和2确定此复制事件不是由自身或者其slave发出,条件3保证该复制事件有可能循环传递  当满足上述则可条件时,判定复制事件是经回路传送过来的,运行效果:  当MySQL复制的IO线程检测到事件存在回路时,会打印如下警告信息:  Detect dual master circular topological structure &然而,对于多个(&=3)节点构成的环形结构(生产环境基本不会使用),例如 M1-& S2 -& S3 -& M1, 上述判断无法起作用  社区反馈:  Percona的Sterward接受此问题#940404 并将其标记为Medium,优先级中等的task, patch查看(percona 5.5.18)  其他发现:  在分析问题和重现现场时,我们曾还事故可能和日志模式有关,因此发现了一个问题,当出现主备之间事件循环传递时,因为主备之间binlog格式不一样,会出现不同的结果,以简化的结构为例:<span style="color: #、server1:row,server2:statement&& server1和server2上都只会执行一次insert(和正常情况一样)<span style="color: #、server1:statement,server2:row&& server1会执行两次insert,而server2只会执行1次<span style="color: #、server1和server2日志模式相同&& 事件循环传递并被不断执行  原因也被找出:row模式日志无法重写成statement模式,而statement模式日志执行后可以写成row模式
IT168企业级
扫一扫关注
行车视线文章推荐

我要回帖

更多关于 mysql事件 的文章

 

随机推荐