1. 程式人生 > >MySQL數據庫詳解

MySQL數據庫詳解

binary 刷新 安裝 每次 服務器性能 匹配 改密 常用 高可用

一、數據庫概述
1、數據庫與文件系統文件系統對比。
數據冗余和不一致性
數據訪問
數據格式相對獨立
數據完整性和原子性
數據的並發訪問
數據的安全性問題
2、數據庫概念
1、DBMS:數據庫管理系統
2、數據模型
層次模型:
按照層次結構的形式組織數據庫的模型
IMS
缺點:大量的冗余數據
網狀模型:
按照網狀結構的形式組織數據庫數據的模型

DBTG
缺點:後期維護困難
關系模型:
按照關系結構(行和列,表)的形式組織數據庫數據的模型。
RDBMS 關系式數據庫管理系統
3、關系
E-R模型
實體:數據對象
聯系:一個或多個實體之間的聯系關系
屬性:實體的某一個特性
4、SQL類型
DML:數據操作語言,操作數據庫中的數據。如select update
DDL:數據描述語言,用來建立數據庫,定義數據關系。如create drop
DCL:數據控制語言,用來控制數據庫的權限組件。如grant revoke
5、數據結構
文件的邏輯關系:
上層:文件
中層:文件系統
下層:磁盤中的數據塊
數據庫的邏輯關系:
上層:數據表(展現給用戶的)
中層:存儲引擎(數據庫的組件)
下層:文件系統
存儲引擎:為存儲數據、管理數據、查詢數據所建立的數據庫實現方法。
6、事務和鎖的概念
事務:SQL語句的批處理。要麽執行成功,要麽保持原樣。
鎖 :
表級鎖:速度快、沖突多
行級鎖:沖突少、速度慢
頁級鎖:折中方案(鎖定相鄰的多行)速度較快,沖突較少
約束:
域約束:限制每個數據的類型
外鍵約束:
唯一性約束,主鍵約束。
7、MySQL常用的存儲引擎:
MyISAM
MySQL誕生起默認的存儲引擎
較高的插入、查詢速度。
不支持事務,行級鎖以及外鍵約束等功能。
InnoDB
支持事務、行級鎖、外鍵約束等功能。
Memory
存在於內存中,通常使用hash存儲數據,速度快。
8、數據的存儲和查詢
存儲管理器(專用的存儲組件,通過DDL來創建數據表結構,再通過DML來保存SQL語句的處理結果)
權限及完整性管理器
事務管理器
文件管理器
緩沖區管理器
查詢管理器(負責接收用戶的查詢請求,理解用戶請求,並將結果交給存儲管理器來真正實現數據管理)
DDL、DML解釋器
查詢執行引擎
9、數據庫的後臺工作模式
單進程多線程的工作模式
1、守護線程
2、應用線程
10、數據庫優化
緩存
用戶的請求不需要每次都消耗系統資源)
線程重用
用戶退出後不撤銷線程,而是分配給其他用戶使用。
提升內存
缺點:不支持海量數據,不支持SMP對稱多處理器架構。
二、MySQL的命令基礎
1、安裝
社區版
GPL
企業版

集群版
主配置文件:/etc/my.cf
[mysqld] 數據庫主進程設置區
datadir=/var/lib/mysql 數據存放目錄
socket=/var/lib/mysql/mysql.sock 套接字文件目錄
user=mysql 指定運行用戶
symbolic-links=0 是否允許軟連接連接一些文件讓系統來調用
[mysqld_safe] 啟動設置區
log-error=/var/log/mysqld.log 錯誤日誌
pid-file=/var/run/mysqld/mysqld.pid 進程id存放文件

2、SQL語句
管理:
設置用戶名密碼
初次設置:mysqladmin -uroot password ‘密碼‘
更改 :mysqladmin -uroot password ‘密碼‘ -p 需要輸入原密碼。
登陸數據庫:
mysql -u root -h localhost -P 3306 -S /var/lib/mysql/mysql.sock -p
-u 指定用戶
-h 指定數據庫地址
-P 指定端口
-S 指定套接字文件
-p 輸入用戶名密碼
創建用戶
create user ‘zhuangsan‘@‘localhost‘ identified by ‘123456‘; 用戶名zhangsan,只能本地登陸,密碼123456
登陸地址:
localhost 本地登陸
IP地址 只能從指定IP地址登陸
% 除本地外的所有地址。
更改密碼
set password=password(‘123‘); 登陸用戶更改自己的密碼(所有用戶都可以操作)
set password for ‘zhuangsan‘@‘localhost‘=password(‘123‘); 為zhangsan用戶在本地登陸更改密碼。(管理員操作)
管理員用戶忘記密碼
更改數據配置文件/etc/my.cnf 在[mysqld]主配置設置區增加 skip-grant-tables
重啟服務器 service mysqld restart
直接執行mysql不加用戶名密碼登陸。
更改root密碼 update mysql.user set password=password(‘890‘) where user=‘root‘;
刪除配置文件中添加的內容,重啟服務,用新密碼登陸。
權限操作:
show grants for ‘zhuangsan‘@‘localhost‘; 查看zhangsan用戶在本地的權限
grant all on aa.* to zhangsan@‘localhost‘ identified by ‘123‘;
revoke drop on aa.* from ‘zhangsan‘@‘localhost‘; 刪除drop權限
all表示所有權限
aa.*表示aa數據庫下的所有表
zhangsan@‘localhost‘表示登陸方式
identified by ‘123‘密碼123
數據操作

create database aa; 創建數據庫
mysql> create table a2( 創建表a2
-> id int unsigned not null auto_increment, 字段名:id、數值類型:int、不允許為負數:unsigned、不允許為空:not null、自增:auto_increment
-> name char(20) not null default ‘‘, 字段名:name、數值類型:char(20)、不許為空、默認值空
-> age int not null default ‘0‘, 字段名:age、默認值:0
-> primary key (id)); 主鍵:id
insert into a2 (name,age) values (‘zhuangsan‘,‘13‘); 為a2表插入記錄
insert into a1 (id,name) select id,name from a2; 將a2中的id,name字段復制到a1表裏面



drop database aa; 刪除數據庫,如果裏面有表會一並刪除。
delete from a2 where id=1;
delete from a2 where age between 20 30; 區間刪除,刪除a2表裏age字段在20到30之間的記錄。
between 值1 值2 匹配區域數據。


update aa.a1 set name=‘lisi‘ where id=1; 將aa數據庫裏a1表的id字段等於1的記錄裏name字段更改為lisi
alter table a1 rename a3; 更改表名,將a2改為a3
alter table aa.a2 modify name char(30) not null default ‘lisi‘; 更改字段屬性
alter table aa.a2 change name username char(30) not null default ‘lisi‘; 連著字段名一塊更改,name改為username
alter table aa.a2 add time datetime; 添加一個字段,類型是datetime
alter table aa.a2 age int first; 表示記錄,first表示添加到第一行。
alter table aa.a2 add age int after id; 在id字段之後添加一個字段。after表示添加到某條字段後。
alter table aa.a2 drop time; 刪除字段

show databases; 查看所有數據庫
use 數據庫; 選擇需要操作的數據庫
show tables; 顯示數據庫中的數據表
describe a1; 查看表結構,或者簡寫成desc a1;也可。
select * from 表\G; 顯示表裏的所有記錄,\G表示豎排顯示。

三、MySQL備份
1、備份方案遵循
數據庫的失效次數減到最少
數據庫的恢復時間減到最少
數據庫失效後,確保盡可能少的數據丟失或根本不丟失
總結:通過特定的方式,將數據庫的必要文件復制到轉儲設備的過程。
2、備份方式
冷備份
熱備份
快照備份,例如LVM寫時復制(copy-on-write)
邏輯備份
提取數據中的所有記錄
mysqldump(主要的備份方式) 單線程,速度慢
物理備份
直接拷貝數據庫文件和日誌來完成備份,多線程、速度更快
雲備份
異地備份
高可用
負載均衡
3、mysqldump備份
mysqldump -uroot -p aa > 1.sql 將aa數據庫備份至1.sql文件
mysqldump -uroot -p test a1 > 2.sql 將test庫中的a1表備份至2.sql數據庫
mysqldump -uroot -p --databases aa bb > 3.sql 同時將aa和bb數據庫備份至3.sql文件,--databases參數表示後面空格隔開的都是數據庫
mysqldump -uroot -p --all-databases > 4.sql --all-databases表示備份所有數據庫
mysql -uroot -p aa < 2.sql 將2.sql還原至aa數據庫中(單個數據庫或多個表還原時需要指定數據庫)
mysql -uroot -p < 3.sql 將多個數據庫還原的時候不需要指定庫名稱。
4、mysqlhotcopy備份
mysqlhotcopy --flushlog -u=‘root‘ -p=‘890‘ --regexp=^a /backup/
--flushlog 標準格式。表示通過日誌進行備份
-u:用戶名 -p:密碼 --regexp:要使用的正則表達式
最後跟備份目錄
使用mysqlhotcopy備份是直接將數據目錄下的數據拷貝過來
還原的時候直接將備份的數據庫cp到數據庫目錄
文件格式:(每個數據表都保存成三個後綴名不同的文件)
.frm 數據表格式
.myd 數據表內容
.myi 數據表索引
mysqldump備份的文件是數據庫端的sql語句集合,而mysqlhotcopy是快速文件意義上的COPY。速度上備份sql語句更快,mysqldump可以適用MYISQM和INNODB引擎,nysqkhotcopy只適用於MYISAM
日誌備份
MySQL常見日誌:
錯誤日誌
log_error=路徑
查詢日誌/一般查詢日誌
general_log=NO/OFF
general_log_file=路徑
log=NO/OFF 全局日誌打開開關
慢查詢日誌
slow_query_log=NO/OFF
slow_query_log_file=路徑
long_query_time=時間
log-slow-queries=路徑 根據版本不同可能需要添加這一條
二進制日誌
記錄更改數據庫狀態的操作。
log-bin=文件名
mysqlbinlog mysql.bin.000001 查看二進制日誌
中繼日誌
主從環境中,從服務器保存數據的日誌文件relay-bin.000001
查看日誌信息:
show global variables like "%log%"; 顯示所有日誌開啟狀態
show global variables like "%long_query%"; 顯示慢查詢設置的時間
show binary logs; 查看當前系統中正在使用的二進制文件
show binlog events in ‘mysql-bin.000001‘; 查看文件的詳細信息
show master status; 查看簡要信息
通過二進制日誌進行備份和還原
二進制日誌管理工具:mysqlbinlog
兩種恢復方式:
根據時間恢復數據:
mysqlbinlog --start-datetime ‘2019-03-01 04:18:13‘ --stop-datetime ‘2019-03-01 04:19:07‘ mysql-bin.000002 | mysql -uroot -p
--start-datetime 選定日誌的開始時間
--stop-datetime 選定日誌的結束時間
| mysql -uroot -p 將截取的日誌輸出到數據庫中
根據數據大小恢復數據:
mysqlbinlog --start-position=189 --stop-position=311 mysql-bin.000002 | mysql -uroot -p
--start-position 選定開始大小
--stop-position 選定結束大小
多機備份:
備份原理:
從服務器通過讀取主服務器的二進制日誌文件來進行數據同步
備份過程:
當客戶端對主服務器進行數據操作時,主服務器的I/O線程將操作寫入二進制日誌文件mysql-bin.000001中。
主服務器給從服務器讀取二進制日誌文件的授權
管理員通過change master to ...語句。將需要讀取的操作寫入master.info中
從服務器的I/O線程根據master.info讀取主服務器的二進制日誌文件
從服務器將讀取的二進制日誌文件寫入本機的繼日誌文件relay-bin.000001中。
從服務器的SQL線程讀取中繼日誌,將SQL語句操作寫入數據庫中。完成備份

主從配置:
將數據單向備份至從服務器

配置文件my.cnf
log-bin=mysql-bin 開啟二進制日誌
server-id=205 server-id表示唯一標識符。
授權
grant replication slave on *.* to ‘zhangsan‘@‘10.248.24.206‘ identified by ‘123456‘;
flush privileges; 刷新權限列表,有些老版本更改權限後需要操作一下

配置文件my.cnf
log-bin=mysql-bin 開啟二進制日誌
server-id=206 server-id表示唯一標識符。
讀取信息:
change master to master_host=‘10.248.24.205‘,master_user=‘zhangsan‘,master_password=‘123456‘,master_log_file=‘mysql-bin.000003‘,master_log_pos=339;
啟用從服務器屬性:
start slave;
查看從服務器狀態信息。
show slave status\G; 保證兩個YES,表示主從正常。
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
主主配置:
將數據雙向備份至對方主機。
配置文件選項:
replicate-do-db=aa 只復制指定數據庫
replicate-do-table=a1 只復制指定數據表
replicate-ignore-table=a1 復制時忽略指定數據表
binlog-do-db 只記錄指定數據庫的更新到二進制文件
binlog-do-table 只記錄指定數據表的更新到二進制文件
binlog-ignore-db 忽略指定數據庫的更新到二進制文件
auto-increment-increment=2 指定自增長的步長為2(用於避免主鍵沖突)
auto-increment-offset=1 指定起始值為1
配置文件:
主:
log-bin=mysql-bin
server-id=205
replicate-do-db=test
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
auto-increment-increment=2
auto-increment-offset=1
備:
log-bin=mysql-bin
server-id=206
replicate-do-db=test
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
auto-increment-increment=2
auto-increment-offset=2
配置方式:
先以第一臺為主第二臺為從進行授權配置。然後以第二臺為主第一臺為從進行授權配置。
多主一從
原理:主服務器正常設置,在從服務器上模擬多個mysql實例,每個實例當作一臺從服務器對應主服務器。
所用到的模塊:mysqld_multi
主服務器設置:略
從服務器設置
配置文件:
[mysqld_multi] 建立模塊區域
mysqld=/usr/bin/mysqld_safe 指定啟動腳本路徑
mysqladmin=/usr/bin/mysqladmin 指定更改密碼腳本所在路徑
log=/tmp/mysqld_multi.log 指定日誌記錄位置

[mysqld1] 創建數據庫實例1(第幾個實例就在mysqld後面加數字)
port=3306 監聽端口
datadir=/var/lib/mysqla/ 數據目錄
pid-file=/var/lib/mysqla/mysqld.pid pid文件
socket=/var/lib/mysqla/mysql.sock 套接字文件
user=mysql 指定運行用戶
server-id=207

[mysqld2] 創建數據庫實例2
port=3307
datadir=/var/lib/mysqlb/
pid-file=/var/lib/mysqlb/mysqld.pid
socket=/var/lib/mysqlb/mysql.sock
user=mysql
server-id=207

初始化MySQL進程,生成數據目錄
mysql_install_db --datadir=/var/lib/mysqla/ --user=mysql
mysql_install_db --datadir=/var/lib/mysqlb/ --user=mysql

更改數據目錄屬主
chown -R mysql /var/lib/mysqla/
chown -R mysql /var/lib/mysqlb/

啟動數據庫實例
mysqld_multi --defaults-file=/etc/my.cnf start 1
mysqld_multi --defaults-file=/etc/my.cnf start 2

登陸實例1並設置從服務器屬性
mysql -P 3306 -S /var/lib/mysqla/mysql.sock
change master to master_host=‘10.248.24.205‘,master_user=‘zhangsan‘,master_password=‘123‘,master_log_file=‘mysql-bin.000001‘,master_log_pos=336;
start slave;
show slave status\G

登陸實例2並設置從服務器屬性
mysql -P 3307 -S /var/lib/mysqlb/mysql.sock
change master to master_host=‘10.248.24.206‘,master_user=‘zhangsan‘,master_password=‘456‘,master_log_file=‘mysql-bin.000001‘,master_log_pos=336;
start slave;
show slave status\G

三、MySQL讀寫分離
將服務器事務性查詢交由主服務器處理,將服務器select類查詢交由從服務器處理。適用於讀取操作遠大於寫操作的場景
提升性能的原因:
1、物理服務器數量增加、提升負荷
2、主從服務器架構,減少了數據庫鎖的消耗
3、提升從服務器性能(MYISAM)
4、數據寫入的性能提升
5、減少網絡阻塞
6、分攤讀取
7、增加冗余
所用中間件:
Mysql proxy
讀寫分離搭建
搭建主從環境:略
配置Java環境
mkdir /amoeba
tar -zxf jdk-7u40-linux-x64.gz
ln -s jdk1.7.0_40/ /amoeba/jdk
vim /etc/profile
JAVA_HOME=/amoeba/jdk
export JAVA_HOME

PATH=$JAVA_HOME/bin:$PATH
export PATH

CLASSPATH=.:$JAVA_HMOE/bin/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH
export CLASSPATH
source /etc/profile 加載一下
java -version 測試Java環境配置
安裝amoeba
unzip amoeba-mysql-1.3.1-BETA.zip -d /usr/local/amoeba 解壓amoeba到指定路徑
chmod -R +x /usr/local/amoeba/bin/ 給amoeba的bin目錄執行權限
配置amoeba
vim /usr/local/amoeba/conf/amoeba.xml 更改amoeba主配置文件(配置文件是默認的根據具體需要更改)
<server> server區域時amoeba的參數配置區域
<property name="port">8066</property> 默認端口
<property name="ipAddress">10.248.24.207</property> amoeba的地址
<property name="user">root</property> 登陸用戶
<property name="password">963</property> 登陸密碼
</server>
<dbServerList> 數據庫列表配置區域
<dbServer name="server1"> 單臺數據庫配置區域,如果有多臺,可以復制粘貼此區域
<property name="port">3306</property> 數據庫端口
<property name="ipAddress">10.248.24.205</property> 數據庫地址
<property name="schema">test</property> 要操作的數據庫名,要操作多臺庫,復制粘貼多臺。
<property name="user">zhangsan</property> 登陸數據庫所用的用戶名
<property name="password">123</property> 登陸數據庫所用的密碼
</dbServer>
<dbServer name="master" virtual="true"> master數據庫池(用於寫入操作),單臺數據庫要加到數據庫池裏,可以配置集群訪問方式
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
<property name="poolNames">server1</property> 加入的數據庫,多臺以分號隔開
</poolConfig>
</dbServer>
<dbServer name="server2">
<property name="port">3306</property>
<property name="ipAddress">10.248.24.206</property>
<property name="schema">test</property>
<property name="user">zhangsan</property>
<property name="password">456</property>
</dbServer>
<dbServer name="slave" virtual="true"> slave數據庫池(用於讀取操作)
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
<property name="poolNames">server2</property>
</poolConfig>
</dbServer>
</dbServerList>

<queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">
<property name="defaultPool">server1</property> 默認操作server1
<property name="writePool">master</property> 寫入數據操作master數據庫池
<property name="readPool">slave</property> 讀取數據操作slave數據庫池
</queryRouter>
更改amoeba啟動腳本
vim ./bin/amoeba
DEFAULT_OPTS="-server -Xms256m -Xmx256m -Xss256k" 將最後的值改為256,要不然顯示有問題。
啟動amoeba
nohup bash -x /usr/local/amoeba/bin/amoeba &
netstat -antp | grep 8066 查看端口是否起來
ps aux 查看有沒有amoeba進程
登陸amoeba代理
mysql -uroot -h 10.248.24.207 -P 8066 -p

MySQL數據庫詳解