设为首页 加入收藏

TOP

MySQL复制(二) --- 二进制日志怎么干活的 (二)
2014-11-23 20:12:37 来源: 作者: 【 】 浏览:72
Tags:MySQL 复制 ---二进制日志 怎么 干活
定,可以尝试分析一下。如果以这种逻辑,使用binlog-ignore-db=ugly筛选时,第三条语句到底要不要写入日志呢?

为了避免在执行可能被过滤的语句时发生错误,请不要编写那种表名,函数名或存储过程名前面加数据库名的语句,而是通过使用use来改变当前数据库

还有一个需要说明的是,只要设置了binlog-do-db,过滤器会无视binlog-ignore-db的设置。

当然对于MySQL复制来说,本身不建议使用过滤器,因为日志是不完整的。

二进制日志和安全

一般来说,一个有REPLICATION SLAVE权限的用户拥有读取Master上发生的所有事件的权限,因此为了安全应该保护该账户不被损害。具体预防的措施有:

  • 尽可能使从防火墙外无法登录该账户
  • 记录所有试图登录到该账户的日志,并将日志放置在一个单独的安全服务器上
  • 加密Master和Slave间所用的连接,例如MySQL的built-in SLL
  • 敏感信息不要放入日志文件中,比如说密码
	# 第二种做法不会把明文密码写入到日志中,更安全些

UPDATE employee SET pass = PASSWORD('foobar')

SET @pass = PASSWORD('foobar');
UPDATE employee SET pass = @pass

触发器

为了在服务器上重放二进制日志,毫无问题的处理各种表的权限,有必要用SUPER权限的用户执行所有语句。但触发器没有被定义使用SUPER权限,所以重要的是以正确的用户作为触发器的定义者去重新创建触发器。CREATE TRIGGER提供了一个DEFINER子句,如果没有给语句指定DEFINER,该语句添加DEFINER子句后被写到二进制日志中,且使用当前用户作为其定义者。

	master>SHOW BINLOG EVENTS FROM 92236 LIMIT 1\G
******************** 1. row ********************
     Log_name: master-bin.000038
          Pos: 92236
   Event_type: Query
    Server_id: 1
  End_log_pos: 92491
         Info: use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER ...

调用触发器的语句被记录到二进制日志,但它没有连接到特定的触发器。相反,当Slave执行该语句时,它会自动执行受该语句影响的表相关联的所有触发器,这意味着可以在Master和Slave上有不同的触发器。

存储过程

存储过程的定义语句的处理和触发器是类似的,CREATE PROCETURE语句也有可选的子语句DEFINER,写入二进制日志的时候,会强制加上该子句的。调用过程和触发器不一样。

	

# 定义存储过程

delimiter $$

CREATE PROCEDURE employee_add(p_name CHAR(64), p_email CHAR(64), p_password CHAR(64))

MODIFIES SQL DATA

BEGIN

DECLARE pass CHAR(64);

set pass = PASSWORD(p_pass)

INSERT INTO employee(name, email, password) VALUES (p_name, p_email, pass);

END $$

delimiter ;

# 调用存储过程

master> CALL employee_add('chunk', 'chuck@example.com', 'abrakadabra');

master> SHOW BINLOG EVENTS FROM 104033\G

******************** 1. row ********************

Log_name: master-bin.000038

Pos: 104033

Event_type: Intvar

Server_id: 1

End_log_pos: 104061

Info: INSERT_ID=1

******************** 2. row ********************

Log_name: master-bin.000038

Pos: 104061

Event_type: Query

Server_id: 1

End_log_pos: 104416

Info: use `test`; INSERT INTO employee(name, email, password) VALUES(

NAME_CONST('p_name',_latin1'chuck' COLLATE 'latin1_swedish_ci'),

NAME_CONST('p_email',_latin1'chuck@example.com' COLLATE 'latin1_swedish_ci'),

NAME_CONST('pass',_latin1'*FEB778934FDSFQOPL7...' COLLATE 'latin1_swedish_ci'))

有四点需要注意:

CALL语句没有被写入二进制日志。取而代之的是,执行语句作为调用的结果被写入二进制日志。

该语句改写为不包含任何对存储过程的参数的引用。取而代之的是,使用NAME_CONST函数为每个参数创建一个单值的结果集

局部声明的变量pass也被换成了NAME_CONST表达式

调用语句写入二进制日志之前,上下文信息已经写入日志,这里指Intvar事件

存储函数

存储过程的定义语句的处理和触发器是类似的,CREATE FUNCTION语句也有可选的子语句DEFINER,写入二进制日志的时候,会强制加上该子句的。调用的时候,存储函数以与触发器相同的方式被复制。有一点需要注意的就是,SELECT语句不会被写入二进制日志,但是一个含有存储函数的SELECT语句是个例外。

对于存储函数还有一个需要提到的是权限问题。CREATE ROUTINE权限是定义一个存储过程或存储函数所必需的。严格说创建一个存储程序不需要其他权限,但它通常根据定义者的权限执行。在Slave上的复制线程在不进行权限检查的情况下执行,这留下了严重的安全漏洞。MySQL 5.0之前的版本没有存储程序,这样不会有问题,因为在Master上违规的语句不会写到二进制日志中。由于存储过程被展开了,只有在Master上成功执行的语句才会写进二进制日志,所以也不会有问题。而存储函数有点不同,它并没有被展开,也就是说有可能在Master和Slave上执行不同的程序分支,带来潜在安全漏洞。在存储函数定义时使用SQL SECURITY DEFINER而不是SQL SECURITY INVOKER可以防止这一点。因为这一点的考虑,MySQL默认要求SUPER权限来定义存储函数。

Events

定义跟其他存储程序一样,也会有DEFINER子句。由于事件由事件调度器调用,因此它们总是以定义者执行从而

首页 上一页 1 2 3 4 5 下一页 尾页 2/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇使用一条INSERT语句完成多表插入 下一篇EBS:Inventory模块的两个package:..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: