西维蜀黍

【MySQL】Best Practice

Naming

Generic

Do

  ...


【MySQL】Logs - Redo Logs (Write-ahead Logging)

Background

我们都知道,事务的四大特性里面有一个是持久性(durability) ,具体来说就是

  • 只要事务提交成功,那么对数据库做的修改就会被永久保存下来了,不可能因为任何原因再回到原来的状态

那么 MySQL 是如何保证一致性的呢?最简单的做法是在每次事务提交的时候,将该事务涉及修改的数据页全部刷新到磁盘中。但是这么做会有严重的性能问题,主要体现在两个方面:

  1. 因为 InnoDB 是以**页(page)**为单位进行磁盘交互的,而一个事务很可能只修改一个数据页里面的几个字节,这个时候将完整的数据页刷到磁盘的话,太浪费资源了!
  2. 一个事务可能涉及修改多个数据页,并且这些数据页在物理上并不连续,因而是随机 I/O(random I/IO) ,随机 I/O写入性能相对很差

因此 MySQL设计了 Redo Log具体来说就是只记录事务对数据页做了哪些修改,这样就能在尽可能的提高性能的同时,保证持久性(durability)。注意到,写入 Redo Log 写入位于磁盘中的 Redo Log file 是顺序 I/O(即通过append-only的方式把修改追加到 Redo Log file 中) ,而真正去磁盘更新存储的数据库数据是随机I/O。

  ...


【MySQL】Logs - Relay Logs

A replica server creates several repositories of information to use for the replication process:

  • The replica’s relay log, which is written by the replication I/O (receiver) thread, contains the transactions read from the replication source server’s binary log. The transactions in the relay log are applied on the replica by the replication SQL (applier) thread.
  • The replica’s connection metadata repository contains information that the replication receiver thread needs to connect to the replication source server and retrieve transactions from the source’s binary log. The connection metadata repository is written to the mysql.slave_master_info table.
  • The replica’s applier metadata repository contains information that the replication applier thread needs to read and apply transactions from the replica’s relay log. The applier metadata repository is written to the mysql.slave_relay_log_info table.
  ...


【MySQL】搭建基于 Binlog Position 的主从复制

Demo

在我的demo中,我是在docker 中创建了两个docker container。

# 这里:
# 1. --restart=unless-stopped:container 会自动启动
# 2. MYSQL_ROOT_HOST=%:root用户可以在任何host上登录
# 3. MYSQL_ROOT_PASSWORD=1234:root 密码为1234
# 4. 3307:3306:将本机的 3307 映射到 container 内部的 3306
$ docker run --name sw-mysql1 --restart=unless-stopped -e MYSQL_ROOT_HOST=% -e MYSQL_ROOT_PASSWORD=1234 -p 3307:3306 -d mysql

$ docker run --name sw-mysql2 --restart=unless-stopped -e MYSQL_ROOT_HOST=% -e MYSQL_ROOT_PASSWORD=1234 -p 3308:3306 -d mysql

值得一提的是,这两个container在默认情况下并不能相互通讯

$ docker network create myNetwork
$ docker network connect myNetwork sw-mysql1
$ docker network connect myNetwork sw-mysql2
  ...


【MySQL】允许远程访问

Run the MySQL Server Process Properly

Make sure that the server is running. If it is not, clients cannot connect to it. For example, if an attempt to connect to the server fails with a message such as one of those following, one cause might be that the server is not running:

$> mysql
ERROR 2003: Can't connect to MySQL server on 'host_name' (111)
$> mysql
ERROR 2002: Can't connect to local MySQL server through socket
'/tmp/mysql.sock' (111)
  ...