1

在mysql上,我有两个数据库“parque_test”和“tabelas_temporais”,并且二进制日志被激活。

修改属于“parque_test”的 InnoDB 表的每个操作都记录在二进制日志中。但是,“parque_test”具有使用临时表来检索结果的存储过程(它们不用于执行更新、删除或插入)。

为了避免在 bin 日志中记录临时表的活动,我设置了“/etc/mysql/my.cnf”文件,以便 mysql 在“parque_test”上注册除“tabelas_temporais”之外的所有活动。

cat /etc/mysql/my.cnf"

...

#log_bin = /var/log/mysql/mysql-bin.log

log_bin=/mysql-log/bin-log

binlog_do_db=parque_test

binlog_do_db=parque_prod

expire_logs_days = 10

max_binlog_size = 100M

#binlog_do_db = include_database_name

#binlog_ignore_db = include_database_name

binlog_ignore_db=tabelas_temporais

...

所有临时表都是在“tabelas_temporais”模式上创建的;但是,二进制日志仍会记录“tabelas_temporais”上的活动,例如,当执行来自“parque_test”的存储过程时,包含如下命令

DROP TEMPORARY TABLE IF EXISTS tabelas_temporais.temp_mod_user;

任何帮助将非常感激!

mysql Ver 14.14 Distrib 5.5.40,适用于使用 readline 6.2 的 debian-linux-gnu (x86_64)

4

1 回答 1

2

如果您不知道它是如何工作的,MySQL 二进制日志中的数据库过滤可能会有些出乎意料。从手册

使用基于语句的日志记录时,以下示例无法正常工作。假设服务器已启动--binlog-ignore-db=sales并且您发出以下语句:

USE prices;UPDATE sales.january SET amount=amount+1000;

UPDATE在这种情况下会记录该语句,因为--binlog-ignore-db仅适用于默认数据库(由该USE语句确定)。因为在语句中明确指定了销售数据库,所以没有过滤语句。但是,当使用基于行的日志记录时,UPDATE语句的效果不会写入二进制日志,这意味着不会sales.january记录对表的更改;在这种情况下,--binlog-ignore-db=sales会导致对销售数据库的主副本中的表所做的所有更改都被忽略以进行二进制日志记录。

简而言之:似乎您可能想要研究ROW基于日志记录而不是STATEMENTor MIXED。然而:

您应该记住,用于记录给定语句的格式不一定与 binlog_format 的值所指示的格式相同。例如,CREATE TABLE 和 ALTER TABLE 等 DDL 语句始终作为语句记录,而不考虑有效的日志记录格式,因此 --binlog-ignore-db 的以下基于语句的规则始终适用于确定是否语句被记录。

DROP也是一个被记录的 DDL。那么,这是否意味着没有办法?相反

.... 临时表仅在使用基于语句的复制时才被记录,而在使用基于行的复制时它们不会被记录。使用混合复制时,通常会记录临时表;用户定义函数 (UDF) 和 UUID() 函数会发生异常......

因此,简而言之,对于“普通”表,在记录的模式中工作时这几乎是不可能的,但是,默认情况下,TEMPORARY 表在ROW基于复制的情况下会被丢弃。这意味着:切换到ROW基于复制,您不需要为真正的临时表使用不同的模式。

但是,如果您需要从STATEMENT/切换MIXEDROW基于复制,请检查其性能,并且如果您经常进行批量更新(很多行受到影响),您的 binlog 会更大一些,因为它会记录每一行更改而不是UPDATE 导致它的单个“简单”语句。

于 2014-12-10T13:25:00.327 回答