管理给自己设置密码

1
> mysql -u root
1
mysql> SET PASSWORD = PASSWORD('123456');

管理员或者有全局权限的用户重设其它用户的密码

方法一

1
> mysql -u root -p
1
2
3
4
mysql> use mysql;
mysql> UPDATE user SET password=PASSWORD("new password") WHERE user='username';
mysql> FLUSH PRIVILEGES;
mysql> exit

方法二

1
> mysql -u root -p
1
2
3
mysql> use mysql; 
mysql> SET PASSWORD FOR username=PASSWORD('new password');
mysql> exit

方法三

1
mysqladmin -u root "old password" "new password"

下载编译mysql

略 (请在 MySQL 官网下载 tar.gz 的 source 源码包)

官网5.6 下载地址: http://dev.mysql.com/downloads/mysql/5.6.html#downloads

编译参数会在其他文章中详细讲解

卸载旧版本

使用下面的命令检查是否安装有MySQL Server

1
> rpm -qa | grep mysql
1
2
3
> rpm -e mysql #普通删除模式 
> rpm -e --nodeps mysql # 强力删除模式,如果使用上面命令删除时,提示有依赖的其它文件,则用该命令可以对其进行强力删除
> yum remove mysql #删除依赖的文件

安装mysql并初始化

把下载好的mysql二进制包放在 /usr/local/

1
2
3
4
5
6
7
8
9
> useradd mysql
> mv /etc/my.cnf /etc/my.conf.d /tmp
> mkdir -p /data/mysql
> chown mysql:mysql /data/mysql
> cd /usr/local/
> tar -xvzf mysql.tar.gz
> chown -R mysql:mysql /usr/local/mysql
> cd /usr/local/mysql
> scripts/mysql_install_db --basedir=/usr/local/mysql --datadir=/data/mysql --user=mysql

启动mysql

创建mysql配置文件

1
2
> vim /etc/my.cnf

1
> chown mysql:mysql /etc/my.cnf

拷贝mysql启动命令

1
2
3
4
5
6
> cp support-files/mysql.server /etc/init.d/mysqld
> vim /etc/init.d/mysqld
basedir=/usr/local/mysql
datadir=/data/mysql
> chkconfig mysqld on
> service mysqld start

这里一定要注意,虽然是在CentOS7系列上安装,CentOS7默认使用systemctl管理程序的启动与关闭,但是mysql5.6提供的脚本是使用service控制程序启动与关闭的脚本,所以需要放在/etc/init.d/下,使用service的方式启动

进入mysql

进入mysql会碰到环境变量的问题,找不到mysql的执行文件

MySQL启动成功后,root默认没有密码,我们需要设置root密码。
设置之前,我们需要先设置PATH,要不不能直接调用mysql
修改/etc/profile文件,在文件末尾添加

1
2
3
> vim /etc/profile
PATH=/usr/local/mysql/bin:$PATH
export PATH

关闭文件,运行下面的命令,让配置立即生效

1
source /etc/profile

现在,我们可以在终端内直接输入mysql进入,mysql的环境了
执行下面的命令修改root密码

1
2
mysql -uroot 
mysql> SET PASSWORD = PASSWORD('123456');

ShadowSocks 最近几年大火, 其简单的配置和优秀的速度让大陆地区的墙内用户爱不释手
本篇文章不讨论Mac & Windows 等图形界面下的应用, 而是让 linux 在命令行界面下, http/https 访问也能登上梯子, 看一看外面的大千世界

最近公司的服务器连接 docker hub hub.docker.com 仓库和 node.js nodejs.org 仓库极其缓慢, 使用了各种国内的各种加速服务才勉强解决了燃眉之急(分别使用了 daocloud 的镜像加速和淘宝的加速服务)

本篇文章就是介绍如何实现 Linux 中的 http/https 请求翻墙的需求

安装 ss 客户端

shadowsocks安装时是不分客户端还是服务器端的, 只不过安装后有两个脚本一个是sslocal代表以客户端模式工作,一个是ssserver代表以服务器端模式工作

1
2
> yum install python-pip
> pip install shadowsocks

在后台启动 ss 客户端

1
> nohup sslocal -s your_server_ip -p your_server_port -l 1080 -k your_server_passwd -t 600 -m rc4-md5 > /dev/null 2>&1 &

注意:

  • 使用的是 sslocal 这个命令,表示 shadowsocks 以客户端模式工作
  • 将上述命令里的 your_server_ip, your_server_port, your_server_passwd 换成自己的, 这三个分别代表服务器ip, 服务器上 shadowsocks 的端口以及密码.后面的 rc4-md5 加密方式也要换成跟 server 端一致。
  • 前面的nohub 和最后的 & 表示后台执行且关闭 session 后仍然在后台执行,否则将会阻塞shell端口.
    为了更方便, 建议新建一个.json的文件, 将上述信息放里面,如新建/etc/shadowsocks.json文件, 内容为:
1
2
3
4
5
6
7
8
9
10
11
{
"server":"your_server_ip", #ss服务器IP
"server_port":your_server_port, #端口
"local_address": "127.0.0.1", #本地ip
"local_port":1080, #本地端口
"password":"your_server_passwd",#连接ss密码
"timeout":300, #等待超时
"method":"rc4-md5", #加密方式
"fast_open": false, # true 或 false。如果你的服务器 Linux 内核在3.7+,可以开启 fast_open 以降低延迟。开启方法: echo 3 > /proc/sys/net/ipv4/tcp_fastopen 开启之后,将 fast_open 的配置设置为 true 即可
"workers": 1 # 工作线程数
}

然后运行一下命令启动shadowsocks

1
> nohup sslocal -c /etc/shadowsocks.json /dev/null 2>&1 &
  • 如果想增加开启自动启动,执行:echo “ nohup sslocal -c /etc/shadowsocks.json /dev/null 2>&1 &” /etc/rc.local
  • 执行ps aux |grep sslocal |grep -v “grep”查看后台sslocal是否运行

安装Privoxy

上述安好了shadowsocks,但它是 socks5 代理,我门在 shell 里执行的命令,发起的网络请求现在还不支持 socks5 代理,只支持 http/https 代理。为了我门需要安装 privoxy 代理,它能把电脑上所有http请求转发给 shadowsocks

1
> yum install privoxy -y
  • 查看 vim /usr/local/etc/privoxy/config 文件,
    先搜索关键字 listen-address 找到 listen-address 127.0.0.1:8118 这一句,保证这一句没有注释,8118就是将来http代理要输入的端口。
    然后搜索 forward-socks5t, 将 #forward-socks5t / 127.0.0.1:1080 . 此句前面的注释去掉, 意思是转发流量到本地的1080端口, 而1080端口正是 ss 监听的端口

启动privoxy

1
2
> systemctl restart privoxy 
> systemctl enable privoxy

转发配置

写在 profile 中

1
2
3
4
> vim /etc/profile
export http_proxy=http://127.0.0.1:8118
export https_proxy=http://127.0.0.1:8118
> source /etc/profile

在当前 session 执行

1
2
export http_proxy=http://127.0.0.1:8118
export https_proxy=http://127.0.0.1:8118

测试翻墙

1
curl www.google.com

问题解决

如果不能访问, 请重启机器, 依次打开shadowsocks和privoxy再测试

1
2
> nohup sslocal -c /etc/shadowsocks.json /dev/null 2>&1 &
> privoxy --user privoxy /usr/local/etc/privoxy/config

本篇文章不再赘述 MySQL 主从搭建的过程, 只介绍主从切换的过程

MySQL 的主从切换分成两种情况

  • 一种情况是主从高可用, 主从切换后, 原主库还要继续同步原从库的数据
  • 另一种情况是一主一从, 主从切换后, 主库下线, 不需要原主库再去同步原从库

第一种情况的主从切换

分别查看主从状态

1
2
# slave 中查看从库的状态
mysql> show slave status\G
1
2
# master 中查看主库的状态
mysql> show slave hosts;

停止从库的 IO_THREAD 线程

先停止 IO_THREAD 线程, 即断开了从主库的 sql 消息接收, 有利于当前数据库完成剩余的数据同步

1
2
3
# slave
mysql> stop slave IO_THREAD;
mysql> show slave status\G

检查是否是如下状态;

1
2
Slave_IO_Running: No
Slave_SQL_Running: Yes

激活从库

在停止 IO_THREAD 线程后, 看到 Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it这个状态后, 就可以操作完全停止从库,并激活为主库啦

1
2
3
4
5
6
7
8
9
mysql> stop slave;  # 完全停止 slave 复制 
mysql> reset slave all; # 完全清空 slave 复制信息
msyql> reset master; # 清空本机上 master 的位置信息(给原主库同步此原从库做准备)
mysql> show binary logs; # 查看当前数据库的 binlog 信息
+----------------+-----------+
| Log_name | File_size |
+----------------+-----------+
| bin-log.000001 | 120 |
+----------------+-----------+

将原主库变为从库

1
2
3
4
5
6
7
8
9
10
# master
mysql> CHANGE MASTER TO
MASTER_HOST='192.168.10.59',
MASTER_PORT=3306,
MASTER_USER='repl',
MASTER_PASSWORD='12345678',
MASTER_LOG_FILE='bin-log.000001',
MASTER_LOG_POS=120;
mysql> start slave;
mysql> show slave status\G

第二种情况的主从切换

第二种情况的主从切换, 切换后, 主库不需要再去同步之前的从库(新主库), 有下线的需求, 这种情况下, 操作流程跟以上差不多, 只不过可以省去如下步骤:

  • 从库中不需要执行reset master了, 因为原主库(现从库)不要再找点啦(Position)
  • 主库直接下线就行了, 不需要执行最后把主库变为从库的操作了

docker容器默认的空间是10G, Pool 大小默认是100G.

查看 docker 信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
> docker info
Containers: 3
Running: 3
Paused: 0
Stopped: 0
Images: 2
Server Version: 1.12.1
Storage Driver: devicemapper
Pool Name: docker-253:0-117441065-pool
Pool Blocksize: 65.54 kB
Base Device Size: 107.4 GB
Backing Filesystem: xfs
Data file: /dev/loop0
Metadata file: /dev/loop1
Data Space Used: 18.32 GB
Data Space Total: 107.4 GB
Data Space Available: 89.05 GB
Metadata Space Used: 12.45 MB
Metadata Space Total: 2.147 GB
Metadata Space Available: 2.135 GB
Thin Pool Minimum Free Space: 10.74 GB
Udev Sync Supported: true
Deferred Removal Enabled: false
Deferred Deletion Enabled: false
Deferred Deleted Device Count: 0
Data loop file: /var/lib/docker/devicemapper/devicemapper/data
WARNING: Usage of loopback devices is strongly discouraged for production use. Use `--storage-opt dm.thinpooldev` to specify a custom block storage device.
Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata
Library Version: 1.02.107-RHEL7 (2016-06-09)
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: host bridge overlay null
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Security Options: seccomp
Kernel Version: 3.10.0-327.28.3.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 6
Total Memory: 7.624 GiB
Name: mobile-quality
ID: NG64:K27K:ASGU:MCBI:NPOZ:Y554:5HME:3INM:UAMI:IIWC:ZQT5:ZKO6
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
Labels:
provider=generic
Insecure Registries:
127.0.0.0/8

Data Space Total: 107.4 GB 这个就是默认的 Pool 大小


调整 container 大小

新 container 的调整

如果想指定默认容器的大小(在启动容器的时候指定),可以在docker配置文件里通过dm.basesize参数指定

直接使用 docker 命令启动服务

1
docker -d --storage-opt dm.basesize=20G

使用 systemctl 命令启动服务

对于使用 systemctl 管理的docker服务, 可以编辑 systemctl 的启动脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
> vim /etc/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
After=network.target

[Service]
Type=notify
ExecStart=/usr/bin/docker daemon -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock --registry-mirror=http://8843165a.m.daocloud.io --storage-driver devicemapper --tl
sverify --tlscacert /etc/docker/ca.pem --tlscert /etc/docker/server.pem --tlskey /etc/docker/server-key.pem --label provider=generic --storage-opt dm.basesize=20G
ExecReload=/bin/kill -s HUP
MountFlags=slave
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Environment=

[Install]
WantedBy=multi-user.target

以上方式适用于新 run 起来的 container, 会获取到新的空间

已存在的 container 的调整

查看所有的虚拟磁盘信息

1
2
3
4
5
6
7
8
9
10
> dmsetup status
docker-253:0-117441065-pool: 0 209715200 thin-pool 39 3039/524288 279539/1638400 - rw discard_passdown queue_if_no_space -
docker-253:0-117441065-bb21427f81836c96a53e7cf0ee97c9e907104ad1ce4d8f2bdade4bbfc0fdd5f5: 0 20971520 thin 17858688 209715199
docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e: 0 20971520 thin 19820928 209715199
docker-253:0-117441065-c57286b3ae5bc1bd675573902d043754aba23349306fd3a52bcd74eed5d144cb: 0 20971520 thin 2968320 209715199
centos-swap: 0 3358720 linear
centos-root: 0 29163520 linear
centos-root: 29163520 71294976 linear
centos-root: 100458496 104849408 linear
centos-root: 205307904 209707008 linear

最上面4条开头写着 docker 的虚拟磁盘就是我们即将操作的对象

其中可以明显的看出, 第一条中带有 pool 的字样, 没错, 这个就是 docker 默认的 pool 大小,现在我们要调整 container 的大小, 暂时不管 pool 的默认配置

其余的三条磁盘信息就是当前宿主机中, 起来的 container 使用的虚拟磁盘, 如果你需要指定其中一个来调整, 那么你需要找到虚拟磁盘和 container name 或 container id 的对应关系, 不要搞错!

对应关系可以使用 docker exec -it xxxx /bin/bash 进入到 container 中使用df -h 命令查看根分区的虚拟磁盘名称
也可以在 linux 中使用 docker inspect xxx 来查看 xxx 容器的详细信息

找到了它们的对应关系之后, 接下来就可以对其调整大小了

找到映射的虚拟磁盘

默认情况下, 所有的虚拟磁盘的映射都在/dev/mapper/

1
2
3
4
5
6
7
8
9
> ls -l
total 0
lrwxrwxrwx 1 root root 7 Dec 7 01:45 centos-root -> ../dm-0
lrwxrwxrwx 1 root root 7 Dec 7 01:45 centos-swap -> ../dm-1
crw------- 1 root root 10, 236 Dec 7 01:45 control
lrwxrwxrwx 1 root root 7 Dec 7 02:20 docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e -> ../dm-3
lrwxrwxrwx 1 root root 7 Dec 7 02:21 docker-253:0-117441065-bb21427f81836c96a53e7cf0ee97c9e907104ad1ce4d8f2bdade4bbfc0fdd5f5 -> ../dm-4
lrwxrwxrwx 1 root root 7 Dec 7 02:30 docker-253:0-117441065-c57286b3ae5bc1bd675573902d043754aba23349306fd3a52bcd74eed5d144cb -> ../dm-5
lrwxrwxrwx 1 root root 7 Dec 7 01:49 docker-253:0-117441065-pool -> ../dm-2

从上面👆的回显也可以看出实际指向的虚拟磁盘文件(是不是有点绕, 这个文件只不过是虚拟磁盘的软连接而已)

接下来我们需要对其进行扩容操作

第一步: 查看指定虚拟磁盘的容量信息

1
2
> dmsetup table docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e
0 20971520 thin 253:2 25

第二步: 计算所需的容量(扇区数量)

假设你想要的容量为 20G

则该值应该为: 20*1024*1024*1024/512 = 41943040

验算: 20G 的值 41943040 = 默认10G 的值 20971520 *2

公式为: x*1024*1024*1024/512

第三步: 挂起虚拟磁盘

1
> dmsetup suspend docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e

没有回显, 没有消息就是好消息😆

第四步: 写入新参数并重新加载进去

1
> dmsetup reload docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e --table '0 41943040 thin 253:2 25'

把上一步计算出来的值, 覆盖到第一步的回显对应的位置中

第五步: 激活挂起的虚拟磁盘

1
> dmsetup resume docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e

如果执行到这一步的时候报错:

1
2
device-mapper: resume ioctl on docker-253:0-1700-pool failed: Invalid argument
Command failed

先不要慌, 稍等片刻, 再重新执行

注意:

由于挂起操作会阻塞住所有的 IO, 为了尽快完成扩容, 我们一般把第三四五步骤用一行命令去执行

1
2
3
> dmsetup suspend docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e \
&& dmsetup reload docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e --table '0 41943040 thin 253:2 25' \
&& dmsetup resume docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e

第六步: 为磁盘扩容

1
2
3
> mount /dev/dm-3 /mnt
> xfs_growfs /mnt
> umount /mnt

需要先挂载再扩容


调整 pool 大小

调整 pool 大小不同于调整 container 的大小, 需要先对其虚拟文件进行扩容, 再对虚拟磁盘扩容

到这里涉及到了三个概念:

  • 虚拟文件大小 —> 硬盘大小/PV/VG
  • 虚拟硬盘设备 —> LV/file system
  • 软连接 —> alias 别名

虚拟硬盘设备是基于虚拟文件的, 就好像我们使用的 lvm 卷, 虚拟硬盘设备就相当于 lv 或是说就相当于我们正在使用的文件系统; 而 docker 中的虚拟文件就好比我们物理机的硬盘, 或是说 PV 与 VG 的大小

  • 在物理服务器中, 磁盘空间不足的话, 我们可以增加硬盘, 条带化成 PV, 再填入到 VG 池中, 然后分配给对应的 LV, 再对其扩容
  • 在 docker 中, 磁盘空间不足的话(pool 不足的话), 我们可以扩充虚拟文件, 然后让虚拟硬盘设备扩容

查看 pool 文件大小信息

1
2
3
4
> ls -lh /var/lib/docker/devicemapper/devicemapper/
total 244M
-rw-------. 1 root root 100G Dec 8 18:27 data
-rw-------. 1 root root 2.0G Dec 8 18:24 metadata

可以看到 data 是100G 大小, 不要担心他实际占用了100G, 这个是精简配置, 实际用多少就占多少空间, 最大100G

第一步: 给文件扩容

上面看到的 data 文件有100G 的大小, 现在我需要200G 的 pool 大小, 所以需要调整 data 文件的属性

1
truncate -s 214748364800 /var/lib/docker/devicemapper/devicemapper/data

第二步: 检查大小

1
2
3
4
> ls -lh /var/lib/docker/devicemapper/devicemapper/                      
total 244M
-rw-------. 1 root root 200G Dec 8 18:35 data
-rw-------. 1 root root 2.0G Dec 8 18:24 metadata

第三步: Reload data loop device

1
2
3
4
5
> blockdev --getsize64 /dev/loop0
107374182400
> losetup -c /dev/loop0
> blockdev --getsize64 /dev/loop0
214748364800

第四步: Reload devicemapper thin pool

第四步基本就是重复上面扩容 container 的步骤, 这里省略了前几步的查看和计算

1
2
3
> dmsetup suspend docker-253:0-1700-pool \
&& dmsetup reload docker-253:0-1700-pool --table '0 419430400 thin-pool 7:1 7:0 128 32768 1 skip_block_zeroing' \
&& dmsetup resume docker-253:0-1700-pool

注意

扩容 pool 涉及到了两个计算

  • data 文件大小的计算
  • devicemapper 扇区数量的计算

上面已经给出了扇区的计算公式: x*1024*1024*1024/512

data 大小的计算公式为: x*1024*1024*1024


参考文档:

https://docs.docker.com/engine/userguide/storagedriver/device-mapper-driver/#/increase-capacity-on-a-running-device
https://segmentfault.com/a/1190000002931564
http://www.linuxidc.com/Linux/2015-01/112245.htm
http://www.projectatomic.io/blog/2016/03/daemon_option_basedevicesize/

在开启了 GTID 功能的 MySQL 数据库中, 不论是否使用了 GTID 的方式做了主从同步, 导出导入时都需要特别注意数据库中的 GTID 信息.

导出

1
2
➜  mysqldump -uroot -p userdb > userdb.sql
Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events

mysql提示: 当前数据库实例中开启了 GTID 功能, 在开启有 GTID 功能的数据库实例中, 导出其中任何一个库, 如果没有显示地指定--set-gtid-purged参数, 都会提示这一行信息. 意思是默认情况下, 导出的库中含有 GTID 信息, 如果不想导出包含有 GTID 信息的数据库, 需要显示地添加--set-gtid-purged=OFF参数. 于是乎, dump 变成了如下样子

➜ mysqldump -uroot -p --set-gtid-purged=OFF userdb > userdb.sql

使用以上这条命令 dump 出来的库是不包含 GTID 信息的

导入

导入的时候也分两种, 一种是导入带有 GTID 的信息的库, 一种是导入不带有 GTID 信息的库

不带有 GTID 信息

不带有 GTID 信息的 dump 文件, 不管目标数据库实例是否开启了 GTID 功能, 且不管数据库实例是否已有其他 GTID 信息, 都可以顺利导入

带有 GTID 信息

带有 GTID 信息的 dump 文件, 要求目标数据库实例必须开启 GTID 功能, 且当前数据库中无其他 GTID 信息. 如果目标数据库中已经记录了一条或一条以上的 GTID 信息, 那么在导入数据库时会报出类似如下的错误❌

1
2
3
➜  mysql -uroot -p userdb < userdb.sql
Password:xxxxxxxx
ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.

在 mysql5.7版本中加入了多 channel 的特性, 一台数据库实例可以同时与多个主库同步, 实现多主一从架构, 但是假如现在数据库实例中开启了 GTID, 并以 GTID 的方式与 A 主库和 B 主库同步,那么现在的 slave 中就记录有两条 GTID 信息. 在导入带有新 GTID 信息的库时, 会报错, 要求你清除掉目标数据库实例中所有的 GTID 信息. 在这种情况下, 问题就比较严重了, 因为我的这台数据库已经和两台主库建立主从关系, 现在为了导入一个新库, 需要 reset 掉所有同步信息(GTID 信息)

这个时候你有两个选择:

  1. 重新 dump 数据库, 使用--set-gtid-purged=OFF的参数禁止🚫导出 GTID 信息,再 load 进目标数据库
  2. 在目标数据库中执行mysql> reset slave all; mysql> reset master; 清空所有 GTID 信息之后就可以导入了

sql_mode

  • ANSI
  • TRADITIONAL
  • STRICT_TRANS_TABLES

sql_mode为空

最宽松的模式, 即使有错误既不会报错也不会有警告⚠️

ANSI

宽松模式,对插入数据进行校验,如果不符合定义类型或长度,对数据类型调整或截断保存,报warning警告

TRADITIONAL

严格模式,当向mysql数据库插入数据时,进行数据的严格校验,保证错误数据不能插入,报error错误。用于事物时,会进行事物的回滚

STRICT_TRANS_TABLES

严格模式,进行数据的严格校验,错误数据不能插入,报error错误

NO_ENGINE_SUBSTITUTION

no_engine_subtitution的作用:mysql 在create table 时可以指定engine子句(指定存储引擎),如果把引擎指定成一个并不存在的引擎, 这个时候mysql可以有两种行为供选择

  • 直接报错
  • 把表的存储引擎替换成innodb

如果 sql_mode 存在 no_engine_subtitution 的时候 ===> 直接报错

如果 sql_mode 不存在 no_engine_subtitution 的时候 ===> 把表的存储引擎替换成innodb

查询 sql_mode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
mysql>  select @@sql_mode;
+------------------------+
| @@sql_mode |
+------------------------+
| NO_ENGINE_SUBSTITUTION |
+------------------------+
1 row in set (0.00 sec)

mysql> select @@global.sql_mode;
+------------------------+
| @@global.sql_mode |
+------------------------+
| NO_ENGINE_SUBSTITUTION |
+------------------------+
1 row in set (0.00 sec)

mysql> select @@session.sql_mode;
+------------------------+
| @@session.sql_mode |
+------------------------+
| NO_ENGINE_SUBSTITUTION |
+------------------------+
1 row in set (0.00 sec)

在线修改 sql_mode

SET [GLOBAL|SESSION] sql_mode='modes'

当前 session 生效

1
mysql> set sql_mode=`NO_FIELD_OPTIONS,HIGH_NOT_PRECEDENCE`;

全局生效

1
mysql> set global sql_mode=`NO_FIELD_OPTIONS,HIGH_NOT_PRECEDENCE`

离线修改 sql_mode

1
2
3
➜  ~ vim /etc/my.cnf

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

参考文档:

在一台 MySQL5.7 的服务器上磁盘使用空间突然爆满, 查看 mysql 数据目录下的文件发现,有个叫ibtmp1的文件大小达到了160GB.

后经过查询得知, ibtmp1文件是 MySQL5.7的新特性,MySQL5.7使用了独立的临时表空间来存储临时表数据,但不能是压缩表。临时表空间在实例启动的时候进行创建,shutdown的时候进行删除。即为所有非压缩的innodb临时表提供一个独立的表空间,默认的临时表空间文件为ibtmp1,位于数据目录。我们可通过innodb_temp_data_file_path参数指定临时表空间的路径和大小,默认12M。只有重启实例才能回收临时表空间文件ibtmp1的大小。create temporary table和using temporary table将共用这个临时表空间

1
2
3
4
5
6
7
mysql> show variables like 'innodb_temp_data_file_path';
+----------------------------+-----------------------+
| Variable_name | Value |
+----------------------------+-----------------------+
| innodb_temp_data_file_path | ibtmp1:12M:autoextend |
+----------------------------+-----------------------+
1 row in set (0.00 sec)

物理文件

1
2
➜  ~ du -sh ibtmp1 
160G ibtmp1

释放这个临时表空间的唯一办法是重启数据库


官方文档: https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_temp_data_file_path

在配置文件中配置有binglog_format=row的数据库产生的 binglog 日志是不能以正常的mysqlbinlog logfile的方式打开的, 默认情况下只能看到一些经过base-64编码的信息

  • 从MySQL 5.1.28开始,mysqlbinlog多了个参数–verbose(或-v),将改动生成带注释的语句,如果使用两次这个参数(如-v -v),会生成字段的类型、长度、是否为null等属性信息
  • 加–base64-output=DECODE-ROWS参数还可以去掉BINLOG开头的信息
1
mysqlbinlog -v -v --base64-output=DECODE-ROWS mysql-bin.000003

使用 mysqlbinlog 命令查看 binlog 日志时出现mysqlbinlog: unknown variable 'default-character-set=utf8mb4'的报错, 原因是在 mysql 的配置文件中, 我设置默认字符集为utf8mb4此字符集为 utf8 的扩展字符集,支持保存 emoji😈 表情, 解决方案如下

1
2
➜  ~ mysqlbinlog mysql-bin.000256
mysqlbinlog: unknown variable 'default-character-set=utf8mb4'

原因是mysqlbinlog这个工具无法识别binlog中的配置中的default-character-set=utf8这个指令

解决的办法有两个:

  1. /etc/my.cnf中配置的default-character-set = utf8mb4修改为character-set-server = utf8mb4 但是这种修改方法需要重启数据库, 在线上业务库中使用这种方法查看 binlog 日志并不划算~
  2. mysqlbinlog --no-defaults mysql-bin.000256 完美解决~