目錄
- 安裝
- 範例:二進位制安裝
- mysql基礎
- 範例:mysql客戶端登入,執行指令碼
- 範例:管理使用者、許可權,增改鎖
- 範例:檢視預設字符集和排序規則
- 常用SQL
- 範例:資料庫DDL: CREATE , DROP ,ALTER
- 範例:資料表DDL: CREATE , DROP ,ALTER
- 範例:DML:INSERT, DELETE, UPDATE
- 範例:DQL單表查詢語句
- 範例:DQL多表子查詢
- 範例:DQL多表查詢union/join
- 範例:sql指令碼注意事項
- mysql常用功能
- 範例:備份/還原前全域性鎖
- 範例:表write、read鎖
- 範例:使用事務ACID特性完成一系列操作
- 範例:kill事務鎖
- 日誌管理
- 事務日誌transaction log
- 範例:事務日誌及效能說明(redo undo)
- 範例:檢視錯誤日誌(.err)
- 範例:開啟通用日誌(記錄操作語句)
- 範例:二進位制日誌配置(binlog備份)
- 事務日誌transaction log
- 備份和恢復
- 範例:冷備份和恢復
- 範例:mysqldump實現完全備份和恢復
- 範例:利用binlog二進位制日誌增量備份和還原
- 主從複製
- 範例:mariadb實現主從複製
安裝
範例:二進位制安裝
流程
1、檔案準備:
相關包:libaio numactl-libs ncurses-compat-libs
mysql包:https://dev.mysql.com/downloads/,找lts長期支援的。
2、伺服器環境準備
建立組,建立使用者,指定id
解壓縮mysql指定目錄,授權,建立軟連線
建立data目錄
修改環境變數,建立service
3、初始化
資料庫生成
###################################################
##1、檔案準備
[root@rocky31 ~]$yum -y install libaio numactl-libs ncurses-compat-libs
##-O指定名稱,避免某些下載名稱過長或有亂碼
[root@rocky31 ~]$wget -O mysql-8.4.0-linux-glibc2.28-x86_64.tar.xz 'https://dev.mysql.com/get/Downloads/MySQL-8.4/mysql-8.4.0-linux-glibc2.28-x86_64.tar.xz'
###################################################
##2、伺服器環境準備
##建立系統組、使用者,1000以內為系統組、使用者,確認801未用
[root@rocky31 ~]$grep 801 /etc/passwd
[root@rocky31 ~]$grep 801 /etc/group
##-g指定id,-r指定建立系統組、系統使用者
[root@rocky31 ~]$groupadd -g 801 -r mysql
##建立系統使用者,-r系統使用者,-u指定id,-g指定組,-s指定預設shell(nologin不登入),-d指定主目錄,-c描述,最後加使用者名稱稱
[root@rocky31 ~]$useradd -r -u 801 -g mysql -s /sbin/nologin -c "mysql" mysql
##MySQL官方推薦的標準安裝路徑/usr/local/mysql,建立軟連線,並授權
[root@rocky31 ~]$tar xvf mysql-8.4.0-linux-glibc2.28-x86_64.tar.xz -C /usr/local
[root@rocky31 ~]$ln -s /usr/local/mysql-8.4.0-linux-glibc2.28-x86_64/ /usr/local/mysql
[root@rocky31 ~]$chown -R mysql.mysql /usr/local/mysql/
##增加環境變數
[root@rocky31 ~]$echo 'PATH=/usr/local/mysql/bin:$PATH' > /etc/profile.d/mysql.sh
[root@rocky31 ~]$. /etc/profile.d/mysql.sh
##增加資料目錄
[root@rocky31 ~]$cat > /etc/my.cnf <<EOF
> [mysqld]
> datadir=/data/mysql
> EOF
[root@rocky31 ~]$mkdir /data/mysql -p
[root@rocky31 ~]$chown -R mysql.mysql /data/mysql/
##增加service
[root@rocky31 ~]$cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
[root@rocky31 ~]$chkconfig --add mysqld
[root@rocky31 ~]$systemctl cat mysqld.service | grep start
Description=LSB: start and stop MySQL
Restart=no
ExecStart=/etc/rc.d/init.d/mysqld start
####################################################
##初始化,--initialize-insecure不設定root密碼,指定mysql使用者,--datadir指定mysql目錄,執行完會看到初始化的檔案
[root@rocky31 ~]$mysqld --initialize-insecure --user=mysql --datadir=/data/mysql
##啟動mysqld服務,可以使用journalctl -f -u實時重新整理日誌
[root@rocky31 ~]$systemctl start mysqld.service
[root@rocky31 ~]$journalctl -f -u mysqld
-- Logs begin at Mon 2024-07-01 19:47:09 CST. --
7月 02 10:37:31 rocky31 systemd[1]: Starting LSB: start and stop MySQL...
7月 02 10:37:31 rocky31 mysqld[3155]: Starting MySQL.
7月 02 10:37:31 rocky31 mysqld[3163]: Logging to '/data/mysql/rocky31.err'.
7月 02 10:37:34 rocky31 mysqld[3155]: ..
7月 02 10:37:34 rocky31 mysqld[3322]: [ 確定 ]
7月 02 10:37:34 rocky31 systemd[1]: Started LSB: start and stop MySQL.
##登入成功,輸入exit或\q退出
[root@rocky31 ~]$mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
##修改密碼後,需要-p輸入密碼才能登入,否則報錯,無-u預設當前使用者登入
[root@rocky31 ~]$mysqladmin -uroot password '123456'
[root@rocky31 ~]$mysql
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
[root@rocky31 ~]$mysql -p'123456'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
mysql基礎
範例:mysql客戶端登入,執行指令碼
##-h, --host= 伺服器主機 ,預設為localhost
##-p, --passowrd= 使用者密碼 ,建議使用-p,預設為空密碼
##-P, --port= 伺服器埠
##-D, --database= 指定預設資料庫
##-e "SQL" 執行SQL命令
##-V, --version 顯示版本
[root@rocky31 ~]$mysql -e 'show databases'
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
[root@rocky31 ~]$cat >show_db.sql<<EOF
> show databases;
> EOF
[root@rocky31 ~]$mysql <show_db.sql
Database
information_schema
mysql
performance_schema
sys
範例:管理使用者、許可權,增改鎖
##為方便登入,先把密碼置為空
mysql> alter user root@'localhost' identified by '';
Query OK, 0 rows affected (0.00 sec)
##檢視使用者,'USERNAME'@'HOST'
mysql> select user,host from mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+------------------+-----------+
4 rows in set (0.00 sec)
##檢視當前使用者
mysql> select user();
+----------------+
| user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
##建立wang使用者,能從10.0.0.*網段登入,密碼123456
mysql> create user 'wang'@'10.0.0.%' identified by '123456';
Query OK, 0 rows affected (0.01 sec)
##授權,給root使用者授權create、option,否則可能無法給wang使用者全部許可權
mysql> GRANT CREATE USER, GRANT OPTION ON *.* TO 'root'@'localhost';
Query OK, 0 rows affected (0.00 sec)
##重新整理許可權
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT ALL PRIVILEGES ON *.* TO 'wang'@'10.0.0.%';
Query OK, 0 rows affected (0.00 sec)
##修改使用者密碼
mysql> alter user 'wang'@'10.0.0.%' identified by '123';
Query OK, 0 rows affected (0.01 sec)
##重新命名使用者
mysql> rename user wang@'10.0.0.%' to wei;
Query OK, 0 rows affected (0.01 sec)
##授權賬號,給select,insert,update指定hellodb.students庫表
mysql> grant select,insert,update on hellodb.students to 'wang'@'10.0.0.%';
Query OK, 0 rows affected (0.01 sec)
##給hellodb庫所有許可權
mysql> grant all on hellodb.* to 'wang'@'10.0.0.%';
Query OK, 0 rows affected (0.00 sec)
##建立admin賬號,給admin所有許可權,with grant option且能給其它賬戶授權
mysql> create user 'admin'@'%' identified by '123456';
Query OK, 0 rows affected (0.01 sec)
mysql> grant all on *.* to admin@'%' with grant option;
Query OK, 0 rows affected (0.01 sec)
##鎖賬號
mysql> ALTER USER 'wang'@'10.0.0.%' ACCOUNT LOCK;
Query OK, 0 rows affected (0.00 sec)
##解鎖賬號
mysql> alter user wei@'%' account unlock;
Query OK, 0 rows affected (0.00 sec)
##revoke取消許可權,不如用鎖定,避免許可權內容不知道
mysql> revoke all on *.* from 'wang'@'10.0.0.%';
Query OK, 0 rows affected (0.00 sec)
##show grants檢視許可權
mysql> SHOW GRANTS FOR 'wang'@'10.0.0.%'\G
*************************** 1. row ***************************
Grants for wang@10.0.0.%: GRANT USAGE ON *.* TO `wang`@`10.0.0.%`
1 row in set (0.00 sec)
範例:檢視預設字符集和排序規則
[root@rocky31 ~]$mysql -e "show variables like 'collation%';"
+----------------------+--------------------+
| Variable_name | Value |
+----------------------+--------------------+
| collation_connection | utf8mb4_0900_ai_ci |
| collation_database | utf8mb4_0900_ai_ci |
| collation_server | utf8mb4_0900_ai_ci |
+----------------------+--------------------+
[root@rocky31 ~]$mysql -e "show variables like 'character%' ;"
+--------------------------+---------------------------------------------------------------+
| Variable_name | Value |
+--------------------------+---------------------------------------------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8mb3 |
| character_sets_dir | /usr/local/mysql-8.4.0-linux-glibc2.28-x86_64/share/charsets/ |
+--------------------------+---------------------------------------------------------------+
##修改字符集和排序方式為utf8
[root@rocky31 ~]$sed -i.bak '/mysqld/acharacter-set-server=utf8mb4\ncollation-server=utf8mb4_general_ci' /etc/my.cnf
常用SQL
範例:資料庫DDL: CREATE , DROP ,ALTER
##建立資料庫
mysql> create database db1 character set 'utf8' collate 'utf8_bin';
Query OK, 1 row affected, 2 warnings (0.01 sec)
mysql> show create database db1\G
*************************** 1. row ***************************
Database: db1
Create Database: CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8mb3 COLLATE utf8mb3_bin */ /*!80016 DEFAULT ENCRYPTION='N' */
1 row in set (0.00 sec)
##再次建立報錯
mysql> create database db1;
ERROR 1007 (HY000): Can't create database 'db1'; database exists
mysql> show warnings\G
*************************** 1. row ***************************
Level: Error
Code: 1007
Message: Can't create database 'db1'; database exists
1 row in set (0.00 sec)
##使用條件if則不會報錯,也不會建立
mysql> create database if not exists db1;
Query OK, 1 row affected, 1 warning (0.01 sec)
##修改資料庫
mysql> alter database db1 character set utf8 collate utf8_bin;
Query OK, 1 row affected, 2 warnings (0.01 sec)
##刪除資料庫
mysql> drop database db1;
Query OK, 0 rows affected (0.01 sec)
##檢視資料庫
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.01 sec)
範例:資料表DDL: CREATE , DROP ,ALTER
##需要先建立資料庫,使用資料庫後才能建立表;
mysql> create database school;
Query OK, 1 row affected (0.00 sec)
mysql> use school;
Database changed
##表欄位有各種型別,AUTO_INCREMENT PRIMARY KEY自增主鍵,char字元,int整數,decimal小數,enum列舉;
mysql> CREATE TABLE student (
-> id int UNSIGNED AUTO_INCREMENT PRIMARY KEY, name VARCHAR(20) NOT NULL,
-> age tinyint UNSIGNED,
-> height DECIMAL(5,2),
-> gender ENUM('M','F') default 'M'
-> )ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
Query OK, 0 rows affected, 1 warning (0.01 sec)
##表欄位timestamp時間型別,CURRENT_TIMESTAMP當前時間
mysql> create table testdata (id int auto_increment primary key,date timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,name char(3));
Query OK, 0 rows affected (0.01 sec)
##使用查詢結果建立新表
mysql> create table userdata select user,host from mysql.user;
Query OK, 5 rows affected (0.02 sec)
Records: 5 Duplicates: 0 Warnings: 0
##建立相同表結構
mysql> create table student2 like student;
Query OK, 0 rows affected (0.01 sec)
##建立外來鍵foreign key
mysql> create table school ( id int primary key auto_increment,name varchar(10));
Query OK, 0 rows affected (0.02 sec)
mysql> create table teacher(id int primary key auto_increment,name varchar(10), school_id int,foreign key(school_id) references school(id));
Query OK, 0 rows affected (0.01 sec)
##刪除表
mysql> drop table if exists student2;
Query OK, 0 rows affected (0.01 sec)
##修改表名
mysql> ALTER TABLE student RENAME s1;
Query OK, 0 rows affected (0.01 sec)
##修改表結構,增加欄位
mysql> ALTER TABLE s1 ADD gender2 ENUM('m','f');
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
範例:DML:INSERT, DELETE, UPDATE
mysql> desc students;
+-----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------------+------+-----+---------+----------------+
| StuID | int unsigned | NO | PRI | NULL | auto_increment |
| Name | varchar(50) | NO | | NULL | |
| Age | tinyint unsigned | NO | | NULL | |
| Gender | enum('F','M') | NO | | NULL | |
| ClassID | tinyint unsigned | YES | | NULL | |
| TeacherID | int unsigned | YES | | NULL | |
+-----------+------------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
##全插入
mysql> insert students values(null,'wang',18,'M',2,2);
Query OK, 1 row affected (0.01 sec)
##部分插入
mysql> insert students(name,age)values('zhang',20);
Query OK, 1 row affected (0.00 sec)
##更新資料
##注意一定要有限制條件,否則將修改所有行資料,可在配置中增加如下,即MySQL將禁止不帶WHERE子句的UPDATE和DELETE語句
##[mysqld]
##sql_safe_updates = 1
mysql> update students set name='wei' where StuID='27';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
##刪除資料
##儘量不刪除,新增一個deleted標記刪除
mysql> alter table students add is_del bool default false;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
##清空資料
mysql> truncate table students;
Query OK, 0 rows affected (0.04 sec)
範例:DQL單表查詢語句
##指定列,查詢不知道資料量必須加limit限制結果
mysql> select stuid 學員ID,name as 姓名 ,gender 性別 from students limit 3;
+----------+-------------+--------+
| 學員ID | 姓名 | 性別 |
+----------+-------------+--------+
| 1 | Shi Zhongyu | M |
| 2 | Shi Potian | M |
| 3 | Xie Yanke | M |
+----------+-------------+--------+
3 rows in set (0.00 sec)
##ifnull函式判斷null時的顯示
mysql> select stuid,name,ifnull(classID, '無班級 ') from students where classid is null;
+-------+-------------+---------------------------------+
| stuid | name | ifnull(classID, '無班級 ') |
+-------+-------------+---------------------------------+
| 24 | Xu Xian | 無班級 |
| 25 | Sun Dasheng | 無班級 |
+-------+-------------+---------------------------------+
2 rows in set (0.00 sec)
##distinct去重
mysql> select distinct gender from students ;
+--------+
| gender |
+--------+
| M |
| F |
+--------+
2 rows in set (0.00 sec)
##查詢平均年齡
mysql> select sum(age)/count(*) from students where gender ='F';
+-------------------+
| sum(age)/count(*) |
+-------------------+
| 19.0000 |
+-------------------+
1 row in set (0.00 sec)
##group by分組查詢
mysql> select count(*),gender from students group by gender ;
+----------+--------+
| count(*) | gender |
+----------+--------+
| 15 | M |
| 10 | F |
+----------+--------+
2 rows in set (0.00 sec)
##order by 【desc】 排序
mysql> select * from students order by age desc limit 3;
+-------+-------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+-------------+-----+--------+---------+-----------+
| 25 | Sun Dasheng | 100 | M | NULL | NULL |
| 3 | Xie Yanke | 53 | M | 2 | 16 |
| 6 | Shi Qing | 46 | M | 5 | NULL |
+-------+-------------+-----+--------+---------+-----------+
3 rows in set (0.00 sec)
範例:DQL多表子查詢
##子查詢作為單個條件
mysql> SELECT Name,Age FROM students WHERE Age<(SELECT avg(Age) FROM teachers) limit 3;
+-------------+-----+
| Name | Age |
+-------------+-----+
| Shi Zhongyu | 22 |
| Shi Potian | 22 |
| Xie Yanke | 53 |
+-------------+-----+
3 rows in set (0.00 sec)
##子查詢作為多個條件,使用in
mysql> SELECT Name,Age FROM students WHERE Age IN (SELECT Age FROM teachers);
+-------------+-----+
| Name | Age |
+-------------+-----+
| Sun Dasheng | 77 |
+-------------+-----+
1 row in set (0.00 sec)
##用於from子句的子查詢
mysql> SELECT s.ClassID,s.aage FROM (SELECT ClassID,avg(Age) AS aage FROM students WHERE ClassID IS NOT NULL GROUP BY ClassID) AS s WHERE s.aage>30;
+---------+---------+
| ClassID | aage |
+---------+---------+
| 2 | 36.0000 |
| 5 | 46.0000 |
+---------+---------+
2 rows in set (0.00 sec)
範例:DQL多表查詢union/join
##聯合查詢union,合併預設去重,不需要去重需要union all
mysql> SELECT Name,Age FROM students UNION SELECT Name,Age FROM teachers limit 3;
+-------------+-----+
| Name | Age |
+-------------+-----+
| Shi Zhongyu | 22 |
| Shi Potian | 22 |
| Xie Yanke | 53 |
+-------------+-----+
3 rows in set (0.00 sec)
##inner join,內連線,取交集
mysql> select * from students inner join teachers on
-> students.teacherid=teachers.tid;
+-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
| StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender |
+-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 3 | Miejue Shitai | 77 | F |
| 4 | Ding Dian | 32 | M | 4 | 4 | 4 | Lin Chaoying | 93 | F |
| 5 | Yu Yutong | 26 | M | 3 | 1 | 1 | Song Jiang | 45 | M |
+-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
3 rows in set (0.00 sec)
##left outer join,左外連線,左表為主,右表無則顯示null
mysql> select s.stuid,s.name,s.age,s.teacherid,t.tid,t.name,t.age from students as s left outer join
-> teachers as t on s.teacherid=t.tid limit 8;
+-------+-------------+-----+-----------+------+---------------+------+
| stuid | name | age | teacherid | tid | name | age |
+-------+-------------+-----+-----------+------+---------------+------+
| 1 | Shi Zhongyu | 22 | 3 | 3 | Miejue Shitai | 77 |
| 2 | Shi Potian | 22 | 7 | NULL | NULL | NULL |
| 3 | Xie Yanke | 53 | 16 | NULL | NULL | NULL |
| 4 | Ding Dian | 32 | 4 | 4 | Lin Chaoying | 93 |
| 5 | Yu Yutong | 26 | 1 | 1 | Song Jiang | 45 |
| 6 | Shi Qing | 46 | NULL | NULL | NULL | NULL |
| 7 | Xi Ren | 19 | NULL | NULL | NULL | NULL |
| 8 | Lin Daiyu | 17 | NULL | NULL | NULL | NULL |
+-------+-------------+-----+-----------+------+---------------+------+
8 rows in set (0.00 sec)
範例:sql指令碼注意事項
##更新資料注意一定要有限制條件,否則將修改所有行資料,可在配置中增加如下,即MySQL將禁止不帶WHERE子句的UPDATE和DELETE語句
[mysqld]
sql_safe_updates = 1
##儘量不刪除,新增一個deleted標記刪除
mysql> alter table students add is_del bool default false;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
##查詢不知道資料量必須加limit限制結果
mysql> select stuid 學員ID,name as 姓名 ,gender 性別 from students limit 3;
##防止SQL隱碼攻擊,輸入敏感資訊不能有特殊符號、且要限制長度
如使用者輸入在使用者名稱輸入“admin'; --”或“admin'; # ”,即使密碼隨便輸入,萬一資料庫裡有admin賬戶,則能登入
##優先使用join替代子查詢
執行子查詢時,需要為內層查詢語句的查詢結果建立一個臨時表。然後外層查詢語句從臨時表 中查詢記錄。查詢完畢後,再撤銷這些臨時表。因此,子查詢的速度會受到一定的影響。如果查詢的資料量比較大,這種影響就會隨之增大。
可以使用連線(JOIN)查詢來替代子查詢。連線查詢不需要建立臨時表,其速度比子查詢要快,如果查詢中使用到索引的話,效能會更好。
##索引
對於like語句,以 % 或者 _ 開頭的不會使用索引,以 % 結尾會使用索引
mysql常用功能
範例:備份/還原前全域性鎖
##關閉正在開啟的表(清除查詢快取),通常在備份前加全域性讀鎖
mysql> flush table with read lock;
Query OK, 0 rows affected (0.00 sec)
mysql> create database db2;
ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock
##全域性鎖,插入/更新資料會等待,查詢不受影響
mysql> insert students(name,age) values('wei',30);
##解鎖後,插入成功
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
範例:表write、read鎖
##write鎖,當前會話能查詢、修改;其它會話一直等待;
mysql> lock table teachers write;
Query OK, 0 rows affected (0.00 sec)
mysql> unlock tables ;
Query OK, 0 rows affected (0.00 sec)
##read鎖,當前會話只能查詢;其它會話也能查詢;
mysql> lock table teachers read;
Query OK, 0 rows affected (0.00 sec)
mysql> update teachers set age=30 where tid=1;
ERROR 1099 (HY000): Table 'teachers' was locked with a READ lock and can't be updated
mysql> unlock tables ;
Query OK, 0 rows affected (0.00 sec)
範例:使用事務ACID特性完成一系列操作
##為了保證一系列操作為一個整體操作,使用begin開始,rollback回滾,commit提交;
##rollback不能撤銷truncate、drop等DDL操作,只能撤銷DML;
##事務一次性提交,可減少磁碟I/O,提高速度;
##只有在當前會話commit後,其它會話查詢結果才看到最新值;不怕沒修改完斷網;
##Mysql預設隔離級別:可重複讀
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update teachers set age=20 where tid=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> commit;
Query OK, 0 rows affected (0.01 sec)
範例:kill事務鎖
##會話1,開啟begin,不結束
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update teachers set age=50 where tid=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
##會話2,一直等待
mysql> update teachers set age=70 where tid=1;
##會話3,檢視鎖
mysql> SELECT trx_mysql_thread_id,trx_state FROM information_schema.INNODB_TRX;
+---------------------+-----------+
| trx_mysql_thread_id | trx_state |
+---------------------+-----------+
| 30 | RUNNING |
+---------------------+-----------+
1 row in set (0.00 sec)
##檢視執行緒詳細資訊,確認是否可以kill
mysql> show processlist;
+----+-----------------+-----------+---------+---------+-------+------------------------+---------------------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-----------------+-----------+---------+---------+-------+------------------------+---------------------------------------------+
| 5 | event_scheduler | localhost | NULL | Daemon | 11700 | Waiting on empty queue | NULL |
| 30 | root | localhost | hellodb | Sleep | 299 | | NULL |
| 39 | root | localhost | hellodb | Query | 11 | updating | update teachers set age=70 where tid=1 |
| 44 | root | localhost | NULL | Query | 0 | init | show processlist |
+----+-----------------+-----------+---------+---------+-------+------------------------+---------------------------------------------+
4 rows in set, 1 warning (0.00 sec)
##kill掉後會話2執行成功,會話1再操作時會報斷開
mysql> kill 30;
##檢視事務超時時長
mysql> show global variables like 'innodb_lock_wait_timeout' ;
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 50 |
+--------------------------+-------+
1 row in set (0.01 sec)
日誌管理
事務日誌transaction log
範例:事務日誌及效能說明(redo undo)
事務日誌作用:
redo log:可以用來恢復未寫入data file的已成功事務更新的資料
undo log:可以用來在事務失敗時進行rollback
事務日誌效能:
0 提交--日誌緩衝區--每秒寫入到磁碟
1 預設值:提交--日誌緩衝區,同時寫入到磁碟
2 提交--os緩衝區--每秒寫入到磁碟
使用1場景:安全,但效率較低,磁碟I/O較多;
使用2場景:高併發業務,os崩潰比mysql崩潰機率低,效率也高;
修改和檢視事務日誌配置:
如需修改,在/etc/my.cnf中的[mysqld]增加
innodb_flush_log_at_trx_commit=1
##檢視預設值
mysql> show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1 |
+--------------------------------+-------+
1 row in set (0.00 sec)
範例:檢視錯誤日誌(.err)
檢視資料目錄
[root@rocky31 ~]$grep datadir /etc/my.cnf
datadir=/data/mysql
檢視日誌路徑
mysql> SHOW GLOBAL VARIABLES LIKE 'log_error';
+---------------+---------------+
| Variable_name | Value |
+---------------+---------------+
| log_error | ./rocky31.err |
+---------------+---------------+
1 row in set (0.01 sec)
tail -f實時重新整理
[root@rocky31 ~]$tail -f /data/mysql/rocky31.err
或者用linux自帶journalctl日誌-f實時重新整理,-u指定程式
[root@rocky31 ~]$journalctl -fu mysqld
範例:開啟通用日誌(記錄操作語句)
記錄對資料庫的通用操作,包括:錯誤的SQL語句,預設不啟用
開啟後重啟服務
[root@rocky31 ~]$grep general_log /etc/my.cnf
general_log=ON
確認是否開啟
mysql> select @@general_log;
+---------------+
| @@general_log |
+---------------+
| 1 |
+---------------+
1 row in set (0.00 sec)
檢視日誌路徑
mysql> select @@general_log_file;
+-------------------------+
| @@general_log_file |
+-------------------------+
| /data/mysql/rocky31.log |
+-------------------------+
1 row in set (0.00 sec)
驗證
[root@rocky31 ~]$tail -f /data/mysql/rocky31.log
...
2024-07-02T10:26:54.190608Z 9 Query select user()
2024-07-02T10:27:14.498637Z 9 Query show databases
...
範例:二進位制日誌配置(binlog備份)
功能:透過"重放"日誌檔案中的事件來生成資料副本
注意:建議二進位制日誌和資料檔案分開存放
二進位制日誌記錄三種格式:
statement 記錄語句,日誌量較少
row 記錄資料,日誌量較大,可用於備份和恢復
mixed 讓系統自行判定該基於哪種方式進行
二進位制檔案構成:
binlog.000001 日誌檔案,如binlog.000004一直累加
binlog.index 索引檔案,記錄當前已有的二進位制日誌檔案列表
常用配置說明:
sql_log_bin=ON ##開啟二進位制日誌
log_bin=/PATH/BIN_LOG_FILE ##指定檔案位置
binlog_format=ROW ##按行記錄資料
sync_binlog=1 ##啟動二進位制日誌即時同步磁碟功能
都可以使用show variables like檢視當前值
mysql> show variables like 'sql_log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_log_bin | ON |
+---------------+-------+
1 row in set (0.00 sec)
##生成新的二進位制檔案
mysql> flush logs;
Query OK, 0 rows affected (0.01 sec)
備份和恢復
範例:冷備份和恢復
##說明:31為主伺服器;41為準備一套一樣的系統和mysql版本
##冷備份和恢復需要停服務
##31伺服器
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| hellodb |
| information_schema |
| mysql |
| performance_schema |
| school |
| sys |
+--------------------+
6 rows in set (0.00 sec)
##41伺服器
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.01 sec)
##31使用rsync -a完全同步,程式、資料、配置
[root@rocky31 ~]$systemctl stop mysqld.service
[root@rocky31 ~]$rsync -a /usr/local/mysql 10.0.0.41:/usr/local/
[root@rocky31 ~]$rsync -a /data/mysql 10.0.0.41:/data/
[root@rocky31 ~]$rsync -a /etc/my.cnf 10.0.0.41:/etc/
##41開啟mysqld服務,登入驗證
[root@rocky-41 ~]$systemctl start mysqld.service
[root@rocky-41 ~]$mysql
...
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| hellodb |
| information_schema |
| mysql |
| performance_schema |
| school |
| sys |
+--------------------+
6 rows in set (0.01 sec)
mysql> select user,host from mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| admin | % |
| wei | % |
| wang | 10.0.0.% |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+------------------+-----------+
7 rows in set (0.01 sec)
範例:mysqldump實現完全備份和恢復
##31備份,41恢復
##開啟二進位制,最好和資料庫分割槽
[root@rocky31 ~]$cat /etc/my.cnf
[mysqld]
datadir=/data/mysql
binlog_format=row
log_bin=/mysqlbin/
[root@rocky31 ~]$ll /mysqlbin/
總用量 16
-rw-r----- 1 mysql mysql 181 7月 2 19:31 mysql.000001
-rw-r----- 1 mysql mysql 712 7月 2 20:55 mysql.000002
-rw-r----- 1 mysql mysql 158 7月 2 20:55 mysql.000003
-rw-r----- 1 mysql mysql 69 7月 2 20:55 mysql.index
#############################################################
##mysqldump常用備份選項
##-u登入使用者;-p密碼;
##-A所有資料庫;-B: 後跟要備份的資料庫列表
##-F重新整理伺服器日誌
##--master-data=2表示以註釋形式顯示change master to語句;可能名稱需要修改為--source-data;備份還原為2,需要設定主從複製為1;
##--single-transaction開啟事務,保證備份時的資料一致性
##--default-character-set=utf8設定預設字符集
##--flush-privileges在備份之前重新整理許可權
##--events事件排程器;--routines儲存過程和函式;--triggers觸發器;
#############################################################
##全庫備份,重新整理日誌
[root@rocky31 ~]$mysqldump -uroot -p -A -F --master-data=1 --single-transaction --flush-privileges --default-character-set=utf8 > fullback.sql
##備份後二進位制日誌檔案新建了
[root@rocky31 ~]$ll /mysqlbin/
總用量 20
-rw-r----- 1 mysql mysql 181 7月 2 19:31 mysql.000001
-rw-r----- 1 mysql mysql 712 7月 2 20:55 mysql.000002
-rw-r----- 1 mysql mysql 201 7月 2 21:02 mysql.000003
-rw-r----- 1 mysql mysql 158 7月 2 21:02 mysql.000004
-rw-r----- 1 mysql mysql 92 7月 2 21:02 mysql.index
##複製到41
[root@rocky31 ~]$scp fullback.sql 10.0.0.41:
##41恢復時,最好先關閉二進位制日誌,恢復完再開啟日誌
##備份指令碼都是建立庫和插入資料,所以可以直接執行,有判斷,很方便
[root@rocky-41 ~]$mysql -uroot -p'123' -e'set sql_log_bin=off;'
[root@rocky-41 ~]$mysql -p <fullback.sql
[root@rocky-41 ~]$mysql -uroot -p'123' -e'set sql_log_bin=on;'
範例:利用binlog二進位制日誌增量備份和還原
##按照之前完全備份的基礎,31伺服器mysql有變動,41增量還原
##31重新整理日誌,確定上次全量備份後的新日誌檔案為mysql.000005
[root@rocky31 ~]$mysql -e'flush logs;'
[root@rocky31 ~]$ll /mysqlbin/
總用量 24
-rw-r----- 1 mysql mysql 181 7月 2 19:31 mysql.000001
-rw-r----- 1 mysql mysql 712 7月 2 20:55 mysql.000002
-rw-r----- 1 mysql mysql 201 7月 2 21:02 mysql.000003
-rw-r----- 1 mysql mysql 383 7月 2 21:34 mysql.000004
-rw-r----- 1 mysql mysql 158 7月 2 21:34 mysql.000005
-rw-r----- 1 mysql mysql 115 7月 2 21:34 mysql.index
##使用mysqlbinlog將日誌檔案生成sql指令碼傳送到41
[root@rocky31 ~]$mysqlbinlog /mysqlbin/mysql.000005 >new.sql
[root@rocky31 ~]$scp new.sql 10.0.0.41:
##41先關閉二進位制記錄,然後執行,完成增量還原
[root@rocky-41 ~]$mysql -e'set sql_log_bin=off;'
[root@rocky-41 ~]$mysql <new.sql
[root@rocky-41 ~]$mysql -e'set sql_log_bin=on;'
主從複製
範例:mariadb實現主從複製
##部分mysql版本使用master關鍵字會報錯,因此使用mariadb
##實現:32為主有資料,31為空資料庫,實現31從節點只讀,資料和32相同且同步
#########################################################
##32伺服器
##設定服務id,開啟二進位制日誌
[root@anolis-32 ~]$cat >>/etc/my.cnf<<EOF
> [mysqld]
> log_bin=/data/mysqlbin/mysql-bin
> server-id=32
> EOF
##建立目錄並授權,啟動資料庫
[root@anolis-32 ~]$mkdir /data/mysqlbin/ -p && chown mysql.mysql /data/mysqlbin
[root@anolis-32 ~]$systemctl start mariadb.service
##匯入部分資料做驗證
[root@anolis-32 ~]$mysql <hellodb_innodb.sql
[root@anolis-32 ~]$mysql -e 'show databases;'
+--------------------+
| Database |
+--------------------+
| hellodb |
| information_schema |
| mysql |
| performance_schema |
+--------------------+
##建立repluser使用者並授權,用於從節點連線同步資料
[root@anolis-32 ~]$mysql -e 'create user repluser@"10.0.0.%" identified by "123";'
[root@anolis-32 ~]$mysql -e 'grant replication slave on *.* to repluser@"10.0.0.%";'
##全備份,--master-data=1生成change master to語句,傳送給31
[root@anolis-32 ~]$mysqldump -A -F --master-data=1 --single-transaction > all.sql
[root@anolis-32 ~]$scp all.sql 10.0.0.31:
#######################################################
##31伺服器
##設定服務id,且為只讀模式
[root@anolis31 ~]$cat >>/etc/my.cnf<<EOF
> [mysqld]
> server-id=31
> read-only
> EOF
##將32傳送的sql指令碼新增主機號,使用者和密碼,如果埠有修改也可以增加
[root@anolis31 ~]$sed -i.bak "s/^CHANGE MASTER TO/\
> CHANGE MASTER TO master_host='10.0.0.32',\
> master_user='repluser',\
> master_password='123',/" all.sql
##執行指令碼後,完成資料複製,有主節點,能啟動從節點
[root@anolis31 ~]$mysql < all.sql
##啟動從節點,檢視從節點狀態,且資料庫也同步,後續資料也會同步
[root@anolis31 ~]$mysql -e 'start slave;'
[root@anolis31 ~]$mysql -e 'show slave status\G;' | grep "Master_Host\|Slave_IO_Running\|Slave_SQL_Running"
Master_Host: 10.0.0.32
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
[root@anolis31 ~]$mysql -e "show databases;"
+--------------------+
| Database |
+--------------------+
| db2 |
| hellodb |
| information_schema |
| mysql |
| performance_schema |
+--------------------+