Mysql - 从一个小 case 理解 MVCC

原文链接: https://juejin.cn/post/7163934829984088095

从 innoDB 的一致性非锁定读说起

非锁定读和行快照数据

一致性的非锁定读(consistent nonlocking read)是指 InnoDB 存储引擎通过行多版本控制(multi versioning)的方式来读取当前执行时间数据库中行的数据。如果读取的行正在执行 DELETE 或 UPDATE 操作,这时读取操作不会因此去等待行上锁的释放。相反地,InnoDB 存储引擎会去读取行的一个快照数据,下图是关于快照数据的一个简单示图:

阅读更多

mysql 日志文件

日志文件记录了影响 mysql 数据库的各种类型活动,mysql 中常见的日志文件主要包括以下 4 种:

  • 错误日志
  • 二进制日志
  • 慢查询日志
  • 查询日志

这些日志文件可以帮助我们对mysql数据库的运行状态进行诊断,从而更好的进行数据库层面的优化。

阅读更多

Linux 下安装 Mysql 数据库

更新,Centos 7 离线安装 Mysql 5.7

近期的一个项目,需要使用 MySQL 5.7,但是甲方所提供的机器是不能访问外网环境的,所以只能通过离线安装的方式来搞,这里大概记录一下,备忘。

选择 Linux - Generic -> Compressed TAR Archive:(mysql-5.7.18-linux-glibc2.12-x86_64.tar.gz),版本按需下载即可;下面是具体的安装过程。

安装步骤

查询并卸载系统自带的数据库 Mariadb

1
2
3
rpm -qa | grep mariadb
## 如果有的话,返回的是这种: mariadb-libs-5.5.60-1.el7_5.x86_64
rpm -e mariadb-libs-5.5.60-1.el7_5.x86_64 --nodeps

创建用户和用户组

为了数据库管理,对于安装的 MySQL 数据库,生产上我们都会建立一个 mysql用户和mysql用户组。

1
2
3
4
5
6
7
8
9
# 先检查mysql用户和用户组有没有被使用
cat /etc/group | grep mysql
cat /etc/passwd | grep mysql
# 添加 mysql 用户组
groupadd mysql
# 添加mysql用户并加入用户组
useradd -g mysql mysql
# 修改mysql用户的登陆密码(这里根据需要设置,可以略过)
passwd mysql

文件上传

如果甲方提供了 访问 VPN ,那么则通过 VPN 建立连接;或者通过甲方提供的方式将文件上传到指定的机器上

1
2
3
4
5
6
7
8
# 解压安装包,解压后会有一个mysql-5.7.18-linux-glibc2.12-x86_64.tar.gz包
tar -xvf mysql-5.7.18-linux-glibc2.5-x86_64.tar
# 解压 mysql-5.7.18-linux-glibc2.5-x86_64.tar.gz包
tar -zxvf mysql-5.7.18-linux-glibc2.5-x86_64.tar.gz
# 此时会生成一个目录 mysql-5.7.18-linux-glibc2.5-x86_64,将其改名为 mysql
mv mysql-5.7.18-linux-glibc2.5-x86_64 mysql
# 将 mysql 移到 /usr/local/mysql
mv mysql /usr/local/

授权

按照下面的操作执行

1
2
3
4
5
6
7
cd /usr/local/
chown -R mysql mysql/
chgrp -R mysql mysql/
cd mysql/
# 创建 data 目录 /usr/local/mysql/data
mkdir data
chown -R mysql:mysql data

配置文件的创建和配置信息

默认这个配置文件是不存在的,需要创建,并且填入配置信息;在 /usr/local/mysql/ 目录下创建文件并编辑

1
2
cd /usr/local/mysql/
vi my.cnf

具体配置信息大致如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[mysql]
socket=/var/lib/mysql/mysql.sock
default-character-set=utf8

[mysqld]
socket=/var/lib/mysql/mysql.sock
port=3306
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
max_connections=200
character-set-server=utf8
default-storage-engine=INNODB
lower_case_table_names=1
max_allowed_packet=32M
explicit_defaults_for_timestamp=true
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

[mysql.server]
user=mysql
basedir=/usr/local/mysql

安装数据库

进入 /usr/local/mysql/ 目录下,执行安装操作。

1
2
# 执行安装命令
bin/mysql_install_db --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/

安装后,如下信息表示安装成功

2023-03-23 14:32:16 [WARNING] mysql_install_db is deprecated. Please consider switching to mysqld –initialize
2023-03-23 14:32:20 [WARNING] The bootstrap log isn’t empty:
2023-03-23 14:32:20 [WARNING] 2023-03-23T06:32:16.437877Z 0 [Warning] –bootstrap is deprecated. Please consider using –initialize instead
2023-03-23T06:32:16.438432Z 0 [Warning] Changed limits: max_open_files: 1024 (requested 5000)
2023-03-23T06:32:16.438439Z 0 [Warning] Changed limits: table_open_cache: 431 (requested 2000)

安装成功后设置文件及目录权限:

1
2
3
4
# 在 /usr/local/mysql 目录下执行
cp ./support-files/mysql.server /etc/init.d/mysqld
chown 777 my.cnf
chmod +x /etc/init.d/mysqld

启动 mysql

/etc/init.d/mysqld restart

我的机器上是出现了如下的报错

1
2
3
4
 ERROR! MySQL server PID file could not be found!
Starting MySQL.Logging to '/usr/local/mysql/data/localhost.localdomain.err'.
2023-03-23T06:33:05.379438Z mysqld_safe Directory '/var/lib/mysql' for UNIX socket file don't exists.
ERROR! The server quit without updating PID file (/usr/local/mysql/data/localhost.localdomain.pid).

如果 /usr/local/mysql/data/localhost.localdomain.err 这个文件存在,就进去看一下具体原因,如果没有就按照以下步骤执行。

1
2
3
4
5
# 创建 /var/lib/mysql/
cd /var/lib/
mkdir mysql
# 提供读写的权限
chmod 777 /var/lib/mysql

配置环境变量,在配置文件中 export PATH=$PATH:/usr/local/mysql/bin

1
2
3
4
# 修改配置文件 /etc/profile
vi /etc/profile
# 立即生效
source /etc/profile

然后重新启动即可。

获取 mysql 安装后的初始密码

1
2
3
4
[root@localhost mysql]# cat /root/.mysql_secret
# Password set for user 'root@localhost' at 2023-03-23 14:32:16
# 这个就是对应的初始密码,随机生成的
cHx#-%,zRho!

登录 mysql 遇到的问题

1
2
3
mysql -uroot -p
# 此时输入密码后可能出现下面的问题
Can't connect to local MySQL server through socket '/tmp/mysql.sock'

解决方案:
1、首先保证在 my.cnf 文件中 socket 的配置如下:

1
2
3
4
...
[mysqld]
socket = /var/lib/mysql/mysql.sock
...

2、对 /tmp/mysql.sock 和 /var/lib/mysql/mysql.sock 建立软连接

1
ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock

修改密码

1
2
3
# 执行语句如下
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your password';
flush privileges;

添加远程访问权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 切换到 mysql 数据库
use mysql;
# 更新权限
update user set host='%' where user = 'root';
#查询一下是否修改成功
select host,user from user;
# 结果如下表示成功,root用户的host已经修改为'%'
--+-----------+---------------+
--| host | user |
--+-----------+---------------+
--| % | root |
--| localhost | mysql.session |
--| localhost | mysql.sys |
--+-----------+---------------+
# 上面的修改结束后,退出数据库,重启数据库服务生效
/etc/init.d/mysqld restart

设置开机自启动服务

1
2
3
4
5
6
# 将mysqld服务加入到系统服务
chkconfig --level 35 mysqld on
# 检查mysqld服务是否已经生效
chkconfig --list mysqld
# 增加mysqld服务控制脚本执行权限
chmod +x /etc/init.d/mysqld

此时如果通过 远程访问还是访问不通,则可能是因为防火墙的问题;这里有两种解决办法

  • 直接关闭防火墙
    1
    systemctl stop firewalld
  • 开通防火墙,放开对 3306 的拦截
    1
    firewalld-cmd --zone=public --add-port=3306/tcp --permanent

Centos 7 在线安装 Mysql 5.7

最近在搞 Apollo ,熟悉的同学应该知道,Apollo 需要依赖 Mysql。本以为很容易搞定,但是却踩了一路坑,眼高手低,也参考了网上很多博客,果然是残缺就是美!本篇就简单记录一下这个过程,以便后面参考。

环境

| 软件 | 版本|
| ———— | ———— |
|linux | centOS 7|
| jdk | 8 |
| mysql| 5.7.24 |

阅读更多

关于 Mybatis 中 SQL 语句的整理

随着业务的发展,越来越多的应用系统都从一个大的系统分拆成多个小的系统,各个系统之间通过一定的通信协议进行数据交换。这样就会导致一些小的应用系统自己不用去进行数据库的操作,只需要进行一些rpc调用或者缓存就可以拿到数据进行展示。我之前参与的一个项目就是这样的情况,而我也是将近7个多月的时间没有写过一行SQL。

近期参与的一个项目的数据大多都市基于数据库来进行数据交互的,所以免不了的要写大量的 SQL,所以本篇就总结一下一些 SQL 的基本写法,以备后用。

阅读更多