我们可以在 MySQL 5.0 Replication 中做些什么来解决带宽问题?

Abr*_*ram 18 mysql replication mysql-5.5 mysql-5.1 mysql-5.0

我正在开发一个在客户端 PC (Win) 上运行的应用程序,它配置了一个 MySQL 服务器 5.1 实例,它将充当远程主站的只读从站。远程主服务器有几十个模式,但我每个客户端只需要一个,所以我在 my.ini 中提供了replication-do-db设置以仅复制客户端需要的模式。复制有效,但是当我们的客户进入只能通过 3G 无线网络访问互联网的地区时,他们会迅速超出数据计划限制并遇到昂贵的问题。

据我了解,MySQL 将所有模式的所有事务写入单个 binlog 文件,这意味着每个客户端必须下载在主服务器上的每个模式上执行的所有事务,然后在下载后,对每个复制应用数据库过滤器 -客户端的 my.ini 文件中的do-db设置。

为了最大限度地减少这种低效率,我采用了slave_compressed_protocol = 1设置,这似乎将传输的数据减少了 50%,但仍然导致我们的客户快速超过他们的数据限制,从而增加了 3G 账单。

我无法想象我是唯一面临这个问题的人,所以我相信我会通过设置 x = y 来获得关于如何实现这一目标的大量答案。但是,我找不到有关此类设置的任何文档,也找不到推荐的方法。

到目前为止,这是我对可能解决方案的想法,请提供反馈或替代路线:


  1. 为每个模式设置一个“代理”从属(在不同的机器上,或具有不同 MySQL 实例/端口的同一个机器上)
  2. 将代理从服务器配置为仅复制客户端希望复制的一个数据库。
  3. 将客户端的 MySQL 实例配置为相应代理从站的从站。

应该导致客户端仅提取其架构的二进制日志数据。缺点(据我所知)是它极大地增加了我们设置的复杂性,可能使其更加脆弱。

想法?这种方法甚至会奏效吗?

请注意,我们在 RedHat 上运行 MySQL 5.0 服务器,但如果它产生解决方案,我们可以升级到 5.5。

Rol*_*DBA 10

建议 #1:使用分发母版

Distribution Master 是一个 mysql slave,启用 log-bin,启用 log-slave-updates,并且只包含带有BLACKHOLE 存储引擎的表。您可以将replicate-do-db 应用到分发主机并在分发主机上创建二进制日志,该日志仅包含您要进行二进制记录的数据库模式。通过这种方式,您可以减少来自 Distribution Master 的传出二进制日志的大小。

您可以按如下方式设置分发主服务器:

  1. mysqldump 使用 --no-data 选项生成仅模式转储的数据库。
  2. 将仅模式转储加载到分发主机。
  3. 将 Distribution Master 中的每个表转换为 BLACKHOLE 存储引擎。
  4. 设置从具有真实数据的主服务器复制到分发主服务器。
  5. 将replicate-do-db 选项添加到分发主服务器的/etc/my.cnf 中。

对于第 2 步和第 3 步,您还可以编辑仅模式转储并将 ENGINE=MyISAM 和 ENGINE=InnoDB 替换为 ENGINE=BLACKHOLE,然后将编辑过的仅模式转储加载到分发主机中。

仅在第 3 步中,如果要在 Distribution Master 中编写将所有 MyISAM 和 InnoDB 表转换为 BLACKHOLE 的脚本,请运行以下查询并将其输出到文本文件:

mysql -h... -u... -p... -A --skip-column-names -e"SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name', ENGINE=BLACKHOLE;') BlackholeConversion FROM information_schema.tables WHERE table_schema NOT IN ('information_schema','mysql') AND engine <> 'BLACKHOLE'" > BlackholeMaker.sql
Run Code Online (Sandbox Code Playgroud)

将表转换为 BLACKHOLE 存储引擎的脚本的另一个好处是MEMORY 存储引擎表也​​被转换。MEMORY存储引擎表不占用磁盘空间进行数据存储,但会占用内存。将 MEMORY 表转换为 BLACKHOLE 将使 Distribution Master 中的内存保持整洁。

只要您不向分发主机发送任何 DDL,您就可以在让客户端仅复制他们想要的数据库信息之前传输您想要的任何 DML(插入、更新、删除)。

我已经在另一个 StackExchange 站点上写了一篇讨论使用 Distribution Master 的帖子

建议 #2:使用较小的二进制日志和中继日志

如果您将max_binlog_size设置为小得离谱,则可以收集并以较小的块发送二进制日志。还有一个单独的选项来设置中继日志的大小,max_relay_log_size。如果 max_relay_log_size = 0,它将默认为 max_binlog_size 设置的任何值。

建议 #3:使用半同步复制(仅限 MySQL 5.5)

将您的主数据库和多个分发主机设置为 MySQL 5.5。启用半同步复制,以便主库可以快速将 binlog 发送到 Distribution Master。如果您的所有从站都是分发主站,则您可能不需要半同步复制或 MySQL 5.5。如果除分发主服务器之外的任何从服务器具有用于报告、高可用性、被动备用或备份目的的真实数据,则将 MySQL 5.5 与半同步复制结合使用。

建议 #4:使用基于语句的二进制日志而不是基于行的日志

如果 SQL 语句更新表中的多行,则基于语句的二进制日志 (SBBL) 仅存储 SQL 语句。使用基于行的二进制日志 (RBBL) 的相同 SQL 语句将实际记录每一行的行更改。这很明显,传输 SQL 语句将节省二进制日志的空间,通过 RBBL 执行 SBBL。

另一个问题是将 RBBL 与replicate-do-db 结合使用,其中表名前面有数据库。这对从站不利,尤其是对于分发主站。因此,请确保所有 DML 都没有数据库和任何表名前的句点。

  • @Abram 您应该将skip-innodb 添加到/etc/my.cnf。您不能禁用 MyISAM,因为它是一个库存存储引擎。如果分发主机上的任何表最终成为 MyISAM,您将不得不手动执行 ALTER TABLE tblname ENGINE=BLACKHOLE。也许从这个查询创建一个脚本: SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=BLACKHOLE;') AlterCommand FROM information_schema.tables WHERE engine='MyISAM' and table_schema NOT IN ('information_schema' ,'mysql'); 如果您找到任何内容,只需从该查询的输出中转换它们即可。 (2认同)