與網(wǎng)絡(luò)相關(guān)的文件:
1) /etc/sysconfig/network 設(shè)置主機(jī)名稱及能否啟動(dòng)Network
2) /etc/sysconfig/network-scripts/ifcfg-eth0 設(shè)置網(wǎng)卡參數(shù)的文件
3) /etc/modprobe.conf 開機(jī)時(shí)用來設(shè)置加載內(nèi)核模塊的文件
4) /etc/resolv.conf 設(shè)置DNS IP(解析服務(wù)器)的文件
5) /etc/hosts 記錄計(jì)算機(jī)IP對(duì)應(yīng)的主機(jī)名稱或主機(jī)別名
6) /etc/protocols 定義IP數(shù)據(jù)包協(xié)議的相關(guān)數(shù)據(jù),包括ICMP、TCP方面的數(shù)據(jù)包協(xié)議的定義等
與網(wǎng)絡(luò)相關(guān)的啟動(dòng)指令:
1)/etc/init.d/network restart 可以重啟整個(gè)網(wǎng)絡(luò)的參數(shù)
2)ifup eth0(ifdown eth0) 啟動(dòng)或是關(guān)閉某個(gè)網(wǎng)絡(luò)接口,可以通過簡(jiǎn)單的script來處理,這兩個(gè)script會(huì)主動(dòng)到/etc/sysconfig/network-scripts/目錄下
·ifconfig 查詢、設(shè)置網(wǎng)卡與IP網(wǎng)段等相關(guān)參數(shù)
·ifup/ifdown 啟動(dòng)/關(guān)閉網(wǎng)絡(luò)接口
配置IP的三種方法:
1、使用命令設(shè)置:
只是暫時(shí)修改網(wǎng)絡(luò)接口,立即生效,但不永久有效
#ifconfig ethX ip/netmask
# ifconfig eth0 192.168.100.1 設(shè)置eth0的IP
# ifconfig eth0 192.168.100.1 netmask 255.255.255.0 > mtu 8000 設(shè)置網(wǎng)絡(luò)接口值,同時(shí)設(shè)置MTU的值
2、 圖形界面設(shè)置:
system-config-network-gui
system-config-network-tui
輸入setup命令,進(jìn)入圖形界面(配置設(shè)備IP等相關(guān)屬性信息、system-config中的服務(wù)集中在這一面板中),有時(shí)進(jìn)入圖形設(shè)置網(wǎng)絡(luò)接口的界面時(shí)會(huì)出現(xiàn)亂碼,這時(shí)的解決方法是:退出此圖形界面,輸入當(dāng)命令“export LANG=en”,再進(jìn)入圖形界面,亂碼便會(huì)得到改善。
進(jìn)入圖形界面,選擇“Network configuration”
修改后網(wǎng)絡(luò)接口之后,“Ok”、“Save”、“Save&Quit”、“Quit”退出,網(wǎng)絡(luò)接口修改完成。網(wǎng)絡(luò)接口不會(huì)立即生效,一旦生效,便會(huì)永久有效,讓IP生效的解決方法是:
1. #ifdown eth1 && ifup eth1 先禁用,再啟用
2. #service network restart 網(wǎng)絡(luò)服務(wù)重啟
3. #/etc/init.d/network restart 也可以重啟網(wǎng)絡(luò)接口
3、直接編輯配置文件:
#vim /etc/sysconfig/network-scripts/ifcfg-ethX
修改網(wǎng)絡(luò)接口的配置文件,配置文件中的常用的屬性有:
DEVICE=ethX 設(shè)備名
BOOTPROTO=(none | static(手動(dòng)指定地址) | dhcp(動(dòng)態(tài)獲取) | bootp)
ONBOOT={yes | no} 系統(tǒng)啟動(dòng)時(shí),網(wǎng)絡(luò)設(shè)備是否被激活
HWADDR= 物理地址,不可隨便改動(dòng)
IPADDR= IP地址,必須
NETMASK= 子網(wǎng)掩碼,必須
TYPE=Ethernet 默認(rèn)的,一般不要改,此項(xiàng)可以不存在
常用屬性還有:
GATEWAY= 網(wǎng)關(guān)
USERCTL={yes | no} 是否允許普通用戶啟用和禁用網(wǎng)絡(luò)設(shè)備
PEERDNS={yes | no} 若使用dhcp獲取地址,服務(wù)器分配一個(gè)IP地址,是否修改服務(wù)器DNS的默認(rèn)指向(默認(rèn)值為yes)
網(wǎng)絡(luò)接口不會(huì)立即生效,一旦生效,便會(huì)永久有效,讓IP生效的解決方法和第二種方法一樣:
1. #ifdown eth1 && ifup eth1 先禁用,再啟用
2. #service network restart 網(wǎng)絡(luò)服務(wù)重啟
3. #/etc/init.d/network restart 也可以重啟網(wǎng)絡(luò)接口
English »
Afrikaans Albanian Arabic Armenian Azerbaijani Basque Bengali Belarusian Bulgarian Catalan Chinese (Simp) Chinese (Trad) Croatian Czech Danish Dutch English Esperanto Estonian Filipino Finnish French Galician Georgian German Greek Gujarati Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Kannada Korean Lao Latin Latvian Lithuanian Macedonian Malay Maltese Norwegian Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Tamil Telugu Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish
Text-to-speech function is limited to 100 characters
無論是
操作系統(tǒng) (Unix 或者
Windows ),還是應(yīng)用程序 (Web 服務(wù),
數(shù)據(jù)庫(kù) 系統(tǒng)等等) ,通常都有自身的日志機(jī)制,以便故障時(shí)追溯現(xiàn)場(chǎng)及原因。Windows Event Log和
SQL Server Error Log就是這樣的日志, PS: SQL Server 中的錯(cuò)誤日志 (Error Log) 類似于
Oracle 中的alert 文件。
一. 錯(cuò)誤日志簡(jiǎn)介
1. Windows事件日志與SQL Server 錯(cuò)誤日志
Windows事件日志中,應(yīng)用程序里的SQL Server和SQL Server Agent服務(wù),分別對(duì)應(yīng)來源自MSSQLSERVER和SQLSERVERAGENT的日志信息;
SQL Server錯(cuò)誤日志中信息,與Windows事件日志里來源自MSSQLSERVER的日志信息基本一致,不同的是,Windows事件日志里信息為應(yīng)用程序級(jí),較為簡(jiǎn)潔些,而SQL Server錯(cuò)誤日志里通常有具體的數(shù)據(jù)庫(kù)錯(cuò)誤信息。比如:
Windows事件日志中錯(cuò)誤信息:
Login failed for user 'sa'. Reason: Password did not match that for the login provided. [CLIENT: 10.213.20.8]
SQL Server錯(cuò)誤日志中錯(cuò)誤信息:
Login failed for user 'sa'. Reason: Password did not match that for the login provided. [CLIENT: 10.213.20.8]
Error: 18456, Severity: 14, State: 8.
2. 如何理解SQL Server的Error message?
以上面的Error: 18456, Severity: 14, State: 8.為例:
(1) Error,錯(cuò)誤編號(hào),可以在系統(tǒng)表里查到對(duì)應(yīng)的文本信息;
select * From sys.messages where message_id = 18456
(2) Severity,錯(cuò)誤級(jí)別,表明這個(gè)錯(cuò)誤的嚴(yán)重性,一共有25個(gè)等級(jí),級(jí)別越高,就越需要我們?nèi)プ⒁馓幚恚?0~25級(jí)別的錯(cuò)誤會(huì)直接報(bào)錯(cuò)并跳出執(zhí)行,用SQL語句的TRY…CATCH是捕獲不到的;
(3) State,錯(cuò)誤狀態(tài),比如18456錯(cuò)誤,幫助文檔記載了如下狀態(tài),不同狀態(tài)代表不同錯(cuò)誤原因:
1. Error information is not available. This state usually means you do not have permission to receive the error details. Contact your SQL Server administrator for more information.
2. User ID is not valid.
5. User ID is not valid.
6. An attempt was made to use a Windows login name with SQL Server Authentication.
7. Login is disabled, and the password is incorrect.
8. The password is incorrect.
9. Password is not valid.
11. Login is valid, but server access failed.
12. Login is valid login, but server access failed.
18. Password must be changed.
還有文檔未記載的State: 10, State: 16,通常是SQL Server啟動(dòng)帳號(hào)權(quán)限問題,或者重啟SQL Server服務(wù)就好了。
3. SQL Server 錯(cuò)誤日志包含哪些信息
SQL Server錯(cuò)誤日志中包含SQL Server開啟、運(yùn)行、終止整個(gè)過程的:運(yùn)行環(huán)境信息、重要操作、級(jí)別比較高的錯(cuò)誤等:
(1) SQL Server/Windows基本信息,如:版本、進(jìn)程號(hào)、IP/主機(jī)名、端口、CPU個(gè)數(shù)等;
(2) SQL Server啟動(dòng)參數(shù)及認(rèn)證模式、內(nèi)存分配;
(3) SQL Server實(shí)例下每個(gè)數(shù)據(jù)打開狀態(tài)(包括系統(tǒng)和用戶數(shù)據(jù)庫(kù));
(4) 數(shù)據(jù)庫(kù)或服務(wù)器配置選項(xiàng)變更,KILL操作,開關(guān)DBCC跟蹤,登錄失敗等等
(5) 數(shù)據(jù)庫(kù)備份/還原的記錄;
(6) 內(nèi)存相關(guān)的錯(cuò)誤和警告,可能會(huì)DUMP很多信息在錯(cuò)誤日志里;
(7) SQL Server調(diào)度異常警告、IO操作延遲警告、內(nèi)部訪問越界 (也就是下面說到的Error 0);
(8) 數(shù)據(jù)庫(kù)損壞的相關(guān)錯(cuò)誤,以及DBCC CHECKDB的結(jié)果;
(9) 實(shí)例關(guān)閉時(shí)間;
另外,可以手動(dòng)開關(guān)一些跟蹤標(biāo)記(trace flags),來自定義錯(cuò)誤日志的內(nèi)容,比如:記錄如用戶登入登出記錄(login auditing),查詢的編譯執(zhí)行等信息,比較常用的可能是用于檢查死鎖時(shí)的1204/1222 跟蹤標(biāo)記。
通常錯(cuò)誤日志不會(huì)記錄SQL語句的性能問題,如:阻塞、超時(shí)的信息,也不會(huì)記錄Windows層面的異常(這會(huì)在windows事件日志中記載)。
SQL Server Agent錯(cuò)誤日志中同樣也包括:信息/警告/錯(cuò)誤這幾類日志,但要簡(jiǎn)單很多。
4. SQL Server 錯(cuò)誤日志存放在哪里
假設(shè)SQL Server被安裝在X:\Program Files\Microsoft SQL Server,則SQL Server 與SQL Server Agent的錯(cuò)誤日志文件默認(rèn)被放在:
X:\Program Files\Microsoft SQL Server\MSSQL.n\MSSQL\LOG\ ERRORLOG ~ ERRORLOG.n
X:\Program Files\Microsoft SQL Server\MSSQL.n\MSSQL\LOG\SQLAGENT.n and SQLAGENT.out.
如果錯(cuò)誤日志路徑被管理員修改,可以通過以下某種方式找到:
(1) 操作系統(tǒng)的應(yīng)用程序日志里,SQL Server啟動(dòng)時(shí)會(huì)留下錯(cuò)誤日志文件的路徑;
(2) 通過SSMS/管理/錯(cuò)誤日志,SQL Server啟動(dòng)時(shí)會(huì)留下錯(cuò)誤日志文件的路徑;
(3) SQL Server配置管理器里,點(diǎn)擊SQL Server實(shí)例/屬性/高級(jí)/啟動(dòng)參數(shù) (Startup parameters) ;
(4) 通過一個(gè)未記載的SQL語句 (在SQL Server 2000中測(cè)試無效,2005及以后可以):
SELECT SERVERPROPERTY('ErrorLogFileName')
5. SQL Server 錯(cuò)誤日志目錄下的其他文件
在錯(cuò)誤日志目錄下除了SQL Server和SQL Server Agent的日志,可能還會(huì)有以下文件:
(1) 維護(hù)計(jì)劃產(chǎn)生的report文件 (SQL Server 2000的時(shí)候,后來的維護(hù)計(jì)劃log記錄在msdb);
(2) 默認(rèn)跟蹤(default trace) 生成的trace文件,PS: 審計(jì)(Audit) 產(chǎn)生的trace文件在\MSSQL\DATA下;
(3) 全文索引的錯(cuò)誤、日志文件;
(4) SQLDUMP文件,比如:exception.log/SQLDump0001.txt/SQLDump0001.mdmp,大多是發(fā)生Error 0時(shí)DUMP出來的,同時(shí)在錯(cuò)誤日志里通常會(huì)有類似如下記錄:
Error: 0, Severity: 19, State: 0
SqlDumpExceptionHandler: Process 232 generated fatal exception c0000005 EXCEPTION_ACCESS_VIOLATION. SQL Server is terminating this process.
順便說下ERROR 0 的解釋:
You've hit a bug of some kind - an access violation is an unexpected condition. You need to contact Product Support (http://support.microsoft.com/sql) to help figure out what happened and whether there's a fix available.
Is your server up to date with service packs? If not, you might try updating to the latest build. This error is an internal error in sql server. If you are up to date, you should report it to MS.
二. 錯(cuò)誤日志維護(hù)
1. 錯(cuò)誤日志文件個(gè)數(shù)
1.1 SQL Server錯(cuò)誤日志
SQL Server錯(cuò)誤日志文件數(shù)量默認(rèn)為7個(gè):1個(gè)正在用的(ERRORLOG)和6個(gè)歸檔的(ERRORLOG.1 – ERRORLOG.6),可以配置以保留更多(最多99個(gè));
(1) 打開到SSMS/管理/SQL Server Logs文件夾/右擊/配置;
(2) 通過未記載的擴(kuò)展存儲(chǔ)過程,直接讀寫注冊(cè)表也行:
USE [master]
GO
EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'NumErrorLogs', REG_DWORD, 50
GO
--Check current errorlog amout
USE [master]
GO
DECLARE @i int
EXEC xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'NumErrorLogs', @i OUTPUT
SELECT @i
SQL Server作為一個(gè)Windows下的應(yīng)用程序,很多信息是寫在注冊(cè)表里的,自然也可以手動(dòng)打開注冊(cè)表編輯器或?qū)慡HELL去修改注冊(cè)表來作配置。
最后,可以通過 如下SQL語句查看已存在的錯(cuò)誤日志編號(hào)、起止時(shí)間、當(dāng)前大小。
EXEC master..xp_enumerrorlogs
1.2 SQL Server Agent錯(cuò)誤日志
SQL Server Agent錯(cuò)誤日志文件數(shù)量共為10個(gè):1個(gè)正在用的(SQLAGENT.OUT),9個(gè)歸檔的(SQLAGENT.1 - SQLAGENT.9),個(gè)數(shù)不可以修改,但可以配置日志所記載的信息類型:信息、警告、錯(cuò)誤。
(1) 打開到SSMS/SQL Server Agent/Error Logs文件夾/右擊/配置;
(2) 未記載的擴(kuò)展存儲(chǔ)過程:
USE [msdb]
GO
EXEC msdb.dbo.sp_set_sqlagent_properties @errorlogging_level=7
GO
至于@errorlogging_level各個(gè)值的意思,由于沒有文檔記載,需要自己測(cè)試并推算下。
2. 錯(cuò)誤日志文件歸檔
2.1 為什么要?dú)w檔錯(cuò)誤日志?
假設(shè)SQL Server實(shí)例從來沒被重啟過,也沒有手動(dòng)歸檔過錯(cuò)誤日志,那么錯(cuò)誤日志文件可能會(huì)變得很大,尤其是有內(nèi)部錯(cuò)誤時(shí)會(huì)DUMP很多信息,一來占空間,更重要的是:想要查看分析也會(huì)不太方便。
SQL Server/SQL Server Agent 錯(cuò)誤日志有2種歸檔方式,即:創(chuàng)建一個(gè)新的日志文件,并將最老的日志刪除。
(1) 自動(dòng)歸檔:在SQL Server/ SQL Server Agent服務(wù)重啟時(shí);
(2) 手動(dòng)歸檔:定期運(yùn)行如下系統(tǒng)存儲(chǔ)過程
EXEC master..sp_cycle_errorlog; --DBCC ERRORLOG 亦可
EXEC msdb.dbo.sp_cycle_agent_errorlog;--SQL Agent 服務(wù)需在啟動(dòng)狀態(tài)下才有效
2.2 可不可以根據(jù)文件大小來歸檔?
可能有人會(huì)覺得,雖然很久沒歸檔,但是錯(cuò)誤日志確實(shí)不大,沒必要定期歸檔,最好可以根據(jù)文件大小來判斷。有以下幾種方法:
(1) 有些監(jiān)控工具,比如:SQL Diagnostic manager,就有檢測(cè)錯(cuò)誤日志文件大小,并根據(jù)大小來決定是否歸檔的功能;
(2) 自定義腳本也可以,比如:powershell, xp_enumerrorlogs 都可以檢查錯(cuò)誤日志大小;
(3) SQL Server 2012支持一個(gè)注冊(cè)表選項(xiàng),以下語句限制每個(gè)錯(cuò)誤日志文件為5M,到了5M就會(huì)自動(dòng)歸檔,在2008/2008 R2測(cè)試無效:
USE [master]
GO
EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'ErrorLogSizeInKb', REG_DWORD, 5120;
三. 錯(cuò)誤日志查看及告警
錯(cuò)誤日志以文本方式記錄,記事本就可以查看,如果錯(cuò)誤日志很大,可以選擇Gvim/UltraEdit /DOS窗口type errorlog等,這些方式都會(huì)“分頁(yè)”加載,不會(huì)卡住。
1. 錯(cuò)誤日志查看
SQL Server提供了以下2種方式查看:
(1) 日志查看器 (log viewer),除了可以查看SQL Server 與SQL Server Agent的錯(cuò)誤日志,還可以查看操作系統(tǒng)日志、數(shù)據(jù)庫(kù)郵件日志。不過當(dāng)日志文件太大時(shí),圖形界面非常慢;
(2) 未記載的擴(kuò)展存儲(chǔ)過程xp_readerrorlog,另外還有一個(gè)名為sp_readerrorlog的存儲(chǔ)過程,它是對(duì)xp_readerrorlog的簡(jiǎn)單封裝,并且只提供了4個(gè)參數(shù),直接使用xp_readerrorlog即可:
在SQL Server 2000里,僅支持一個(gè)參數(shù),即錯(cuò)誤日志號(hào),默認(rèn)為0~6:
exec dbo.xp_readerrorlog --寫0或null都會(huì)報(bào)錯(cuò),直接運(yùn)行即可
exec dbo.xp_readerrorlog 1
exec dbo.xp_readerrorlog 6
--sql server 2000 read error log
if OBJECT_ID('tempdb..#tmp_error_log_all') is not null
drop table #tmp_error_log_all
create table #tmp_error_log_all
(
info varchar(8000),--datetime + processinfo + text
num int
)
insert into #tmp_error_log_all
exec dbo.xp_readerrorlog
--split error text
if OBJECT_ID('tempdb..#tmp_error_log_split') is not null
drop table #tmp_error_log_split
create table #tmp_error_log_split
(
logdate datetime,--datetime
processinfo varchar(100),--processinfo
info varchar(7900)--text
)
insert into #tmp_error_log_split
select CONVERT(DATETIME,LEFT(info,22),120),
LEFT(STUFF(info,1,23,''),CHARINDEX(' ',STUFF(info,1,23,'')) - 1),
LTRIM(STUFF(info,1,23 + CHARINDEX(' ',STUFF(info,1,23,'')),''))
from #tmp_error_log_all
where ISNUMERIC(LEFT(info,4)) = 1
and info <> '.'
and substring(info,11,1) = ' '
select *
from #tmp_error_log_split
where info like '%18456%'
在SQL Server 2005及以后版本里,支持多達(dá)7個(gè)參數(shù),說明如下:
exec dbo.xp_readerrorlog 1,1,N'string1',N'string2',null,null,N'desc'
參數(shù)1.日志文件號(hào): 0 = 當(dāng)前, 1 = Archive #1, 2 = Archive #2, etc...
參數(shù)2.日志文件類型: 1 or NULL = SQL Server 錯(cuò)誤日志, 2 = SQL Agent 錯(cuò)誤日志
參數(shù)3.檢索字符串1: 用來檢索的字符串
參數(shù)4.檢索字符串2: 在檢索字符串1的返回結(jié)果之上再做過濾
參數(shù)5.日志開始時(shí)間
參數(shù)6.日志結(jié)束時(shí)間
參數(shù)7.結(jié)果排序: N'asc' = 升序, N'desc' = 降序
--sql server 2005 read error log
if OBJECT_ID('tempdb..#tmp_error_log') is not null
drop table #tmp_error_log
create table #tmp_error_log
(
logdate datetime,
processinfo varchar(100),
info varchar(8000)
)
insert into #tmp_error_log
exec dbo.xp_readerrorlog
select *
from #tmp_error_log
where info like '%18456%'
2. 錯(cuò)誤日志告警
可以通過對(duì)某些關(guān)鍵字做檢索:錯(cuò)誤(Error),警告(Warn),失敗(Fail),停止(Stop),而進(jìn)行告警 (database mail),以下腳本檢索24小時(shí)內(nèi)的錯(cuò)誤日志:
declare
@start_time datetime
,@end_time datetime
set @start_time = CONVERT(char(10),GETDATE() - 1,120)
set @end_time = GETDATE()
if OBJECT_ID('tempdb..#tmp_error_log') is not null
drop table #tmp_error_log
create table #tmp_error_log
(
logdate datetime,
processinfo varchar(100),
info varchar(8000)
)
insert into #tmp_error_log
exec dbo.xp_readerrorlog 0,1,NULL,NULL,@start_time,@end_time,N'desc'
select COUNT(1) as num, MAX(logdate) as logdate,info
from #tmp_error_log
where (info like '%ERROR%'
or info like '%WARN%'
or info like '%FAIL%'
or info like '%STOP%')
and info not like '%CHECKDB%'
and info not like '%Registry startup parameters%'
and info not like '%Logging SQL Server messages in file%'
and info not like '%previous log for older entries%'
group by info
當(dāng)然,還可以添加更多關(guān)鍵字:kill, dead, victim, cannot, could, not, terminate, bypass, roll, truncate, upgrade, recover, IO requests taking longer than,但當(dāng)中有個(gè)例外,就是DBCC CHECKDB,它的運(yùn)行結(jié)果中必然包括Error字樣,如下:
DBCC CHECKDB (xxxx) executed by sqladmin found 0 errors and repaired 0 errors.
所以對(duì)0 errors要跳過,只有在發(fā)現(xiàn)非0 errors時(shí)才作告警。
小結(jié)
如果沒有監(jiān)控工具,那么可選擇擴(kuò)展存儲(chǔ)過程,結(jié)合數(shù)據(jù)庫(kù)郵件的方式,作自動(dòng)檢查及告警,并定期歸檔錯(cuò)誤日志文件以避免文件太大。大致步驟如下 :
(1) 部署數(shù)據(jù)庫(kù)郵件;
(2) 部署作業(yè):定時(shí)檢查日志文件,如檢索到關(guān)鍵字,發(fā)郵件告警;
(3) 部署作業(yè):定期歸檔錯(cuò)誤日志,可與步驟(2) 合并作為兩個(gè)step放在一個(gè)作業(yè)里。
English »
Afrikaans Albanian Arabic Armenian Azerbaijani Basque Bengali Belarusian Bulgarian Catalan Chinese (Simp) Chinese (Trad) Croatian Czech Danish Dutch English Esperanto Estonian Filipino Finnish French Galician Georgian German Greek Gujarati Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Kannada Korean Lao Latin Latvian Lithuanian Macedonian Malay Maltese Norwegian Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Tamil Telugu Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish
Text-to-speech function is limited to 100 characters
vmstat一直以來就是linux/unix中進(jìn)行性能監(jiān)控的利器,相比top來說它的監(jiān)控更加系統(tǒng)級(jí),更側(cè)重于系統(tǒng)整體的情況。
首先來看看vmstat的命令的解釋。
可能大家并不陌生,如果需要每隔2秒,生成3次報(bào)告,可以使用vmstat 2 3
對(duì)于命令的輸出解釋如下:
r代表等待cpu事件的進(jìn)程數(shù)
b代表處于不可中斷休眠中的進(jìn)程數(shù),
swpd表示使用的虛擬內(nèi)存的總量,單位是M
free代表空閑的物理內(nèi)存總量,單位是M
buffer代表用作緩沖區(qū)的內(nèi)存總量
cache代表用做高速緩存的內(nèi)存總量
si代表從磁盤交換進(jìn)來的內(nèi)存總量
so代表交換到磁盤的內(nèi)存總量
bi代表從塊設(shè)備收到的塊數(shù),單位是1024bytes
bo代表發(fā)送到塊設(shè)備的塊數(shù)
in代表每秒的cpu中斷次數(shù)
cs代表每秒的cpu上下文切換次數(shù)
us代表用戶執(zhí)行非內(nèi)核代碼的cpu時(shí)間所占的百分比
sy代表用于執(zhí)行那個(gè)內(nèi)核代碼的cpu時(shí)間所占的百分比
id代表處于空閑狀態(tài)的cpu時(shí)間所占的百分比
wa代表等待io的cpu時(shí)間所占的百分比
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 296716 399588 904276 0 0 0 16 639 1285 0 0 100 0 0
0 0 0 296576 399588 904276 0 0 43 11 809 1484 1 1 98 0 0
0 0 0 296576 399592 904276 0 0 53 25 764 1538 0 0 99 0 0
0 0 0 296584 399592 904276 0 0 0 11 716 1502 0 0 100 0 0
0 0 0 296584 399600 904276 0 0 21 16 756 1534 0 0 100 0 0
零零總總說了一大堆,我們舉幾個(gè)例子,一個(gè)是文件的拷貝,這個(gè)最直接的io操作。看看在vmstat的監(jiān)控下會(huì)有什么樣的數(shù)據(jù)變化。
黃色部分代表開始運(yùn)行cp命令時(shí)vmstat的變化,我們拷貝的文件是200M,可以看到空閑內(nèi)存立馬騰出了將近200M的內(nèi)存空間,buffer空間基本沒有變化,這部分空間都放入了cache,同時(shí)從設(shè)備收到的塊數(shù)也是急劇增加,cpu上下文的切換次數(shù)也是從930瞬間達(dá)到了1918,然后慢慢下降,cpu的使用率也是瞬間上升,最后基本控制在20%~30%。
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 296716 399588 904276 0 0 0 16 639 1285 0 0 100 0 0
0 0 0 296576 399588 904276 0 0 43 11 809 1484 1 1 98 0 0
0 0 0 296576 399592 904276 0 0 53 25 764 1538 0 0 99 0 0
0 0 0 296584 399592 904276 0 0 0 11 716 1502 0 0 100 0 0
0 0 0 296584 399600 904276 0 0 21 16 756 1534 0 0 100 0 0
0 0 0 296584 399600 904276 0 0 0 11 930 1625 1 1 98 0 0
1 1 0 93960 399608 1104528 0 0 33427 24 1918 2094 0 23 71 7 0
1 0 0 66440 399592 1131832 0 0 7573 12 1513 1323 0 25 74 2 0
5 0 0 74988 399588 1123188 0 0 2859 33 887 594 0 24 75 1 0
11 0 0 74280 399572 1114952 0 0 1963 15 770 738 3 44 53 0 0
2 0 0 74492 399568 1125008 0 0 3776 16 1014 812 0 20 73 6 0
2 0 0 72640 399560 1126696 0 0 2411 23 975 619 1 21 78 0 0
1 0 0 70532 399556 1128936 0 0 2389 16 1018 732 0 22 77 0 0
2 0 0 75396 399532 1116288 0 0 2795 15 831 673 2 47 51 0 0
2 0 0 79576 399536 1121416 0 0 2901 20 850 688 1 24 63 12 0
0 3 0 67052 399536 1130252 0 0 1493 43708 701 644 0 29 24 47 0
1 0 0 74244 399540 1125600 0 0 1323 19 842 624 0 10 65 25 0
3 0 0 70788 399532 1127728 0 0 2539 21152 936 624 0 18 58 24 0
5 0 0 73164 399532 1120352 0 0 1109 27 458 447 4 71 17 9 0
0 0 0 76120 399532 1125684 0 0 1859 15 957 1182 0 19 80 1 0
0 0 0 76128 399532 1125688 0 0 21 19 679 1399 0 0 98 1 0 --拷貝
工作 完成系統(tǒng)的負(fù)載又逐步恢復(fù)了原值。
對(duì)于文件的操作有了一個(gè)基本認(rèn)識(shí),來看看數(shù)據(jù)庫(kù)級(jí)的操作吧。
首先看看全表掃描的情況。
我們對(duì)于一個(gè)170萬數(shù)據(jù)的表進(jìn)行查詢。可以看到
從設(shè)備收到的塊數(shù)是急劇增加,效果跟文件的拷貝有些類似,但是buffer,cache基本沒有變化。我想這也就是數(shù)據(jù)庫(kù)級(jí)別的操作和系統(tǒng)級(jí)別的根本區(qū)別吧。數(shù)據(jù)庫(kù)的buffer_cache應(yīng)該就是起這個(gè)作用的。
SQL> select count(*)from test where object_id<>1;
COUNT(*)
----------
1732096
[ora11g@rac1 arch]$ vmstat 3
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 166520 399680 1023292 0 0 17 20 6 5 1 1 98 1 0
0 0 0 175800 399680 1023292 0 0 53 11 680 1308 0 0 100 0 0
1 0 0 175800 399680 1023292 0 0 18021 24 1451 1826 2 7 66 25 0
0 0 0 175800 399680 1023292 0 0 53 53 812 1577 0 0 98 2 0
0 0 0 166256 399680 1023292 0 0 0 16 881 1614 1 1 98 0 0
1 0 0 175908 399680 1023292 0 0 21 11 866 1605 0 0 99 0 0
接著來做一個(gè)更為消耗資源的操作,這個(gè)sql不建議在正式環(huán)境測(cè)試,因?yàn)楹芎馁M(fèi)資源
對(duì)一個(gè)170多萬的表進(jìn)行低效的連接。vmstat的情況如下。運(yùn)行了較長(zhǎng)的時(shí)間,過了好一段時(shí)間都沒有結(jié)束,可以看到cpu的使用率已經(jīng)達(dá)到了40~50%,在開始的時(shí)候,從設(shè)備中得到的塊數(shù)急劇增加,然后基本趨于一個(gè)平均值,buffer,cache基本沒有變化。
SQL> select count(*)from test t1,test t2 where t1.object_id=t2.object_id;
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 176024 399688 1023292 0 0 43 11 655 1284 0 0 99 1 0
1 0 0 171420 399688 1023292 0 0 0 16 671 1302 1 1 98 0 0
0 0 0 176164 399688 1023292 0 0 0 11 735 1331 0 1 99 0 0
0 0 0 176164 399688 1023292 0 0 21 25 678 1291 0 0 99 0 0
1 0 0 173452 399688 1023292 0 0 15643 5256 1835 2178 6 12 76 6 0
2 0 0 163048 399688 1023292 0 0 15179 5748 2166 2271 7 12 67 14 0
1 0 0 172072 399688 1023292 0 0 5541 2432 2226 1860 32 6 59 3 0
1 0 0 169964 399688 1023292 0 0 656 24 2322 1656 46 1 50 4 0
1 0 0 169848 399688 1023292 0 0 485 11 2335 1637 48 1 50 2 0
1 0 0 159576 399692 1023288 0 0 448 115 2442 1738 49 1 48 2 0
1 0 0 169344 399692 1023292 0 0 712 11 2351 1701 47 1 50 3 0
1 0 0 169352 399696 1023288 0 0 619 24 2332 1649 48 1 49 2 0
1 0 0 169360 399696 1023292 0 0 467 11 2339 1623 47 1 50 2 0
1 0 0 159848 399700 1023288 0 0 693 16 2318 1673 48 1 48 3 0
1 0 0 169368 399700 1023292 0 0 467 11 2309 1660 47 1 50 3 0
2 0 0 169368 399700 1023292 0 0 467 28 2329 1624 48 1 50 2 0
來看看并行的效果。最后返回的條數(shù)有近億條,這也就是這個(gè)連接低效的原因所在,但是在vmstat得到的信息來看和普通的數(shù)據(jù)查詢還是有很大的差別。
首先是急劇消耗io,同時(shí)從內(nèi)存中也取出了一塊內(nèi)存空間。然后io基本趨于穩(wěn)定,開始急劇消耗cpu資源。可以看到cpu的使用率達(dá)到了90%以上。
SQL> select count(*)from test t1,test t2 where t1.object_id=t2.object_id;
COUNT(*)
----------
221708288
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 175048 399748 1023292 0 0 0 20 665 1274 0 0 100 0 0
0 0 0 175048 399748 1023292 0 0 21 11 657 1286 0 0 100 0 0
0 0 0 165644 399748 1023292 0 0 0 16 715 1310 1 1 98 0 0
0 0 0 175056 399748 1023292 0 0 0 11 664 1284 0 0 99 0 0
0 0 0 175056 399748 1023292 0 0 21 24 640 1289 0 0 99 0 0
0 4 0 142364 399748 1025408 0 0 5957 988 1407 1869 10 8 64 18 0
0 0 0 132092 399748 1025444 0 0 12520 4939 1903 2556 14 11 32 43 0
0 2 0 140248 399748 1025444 0 0 10477 3973 1728 2427 11 7 29 53 0
2 0 0 136776 399748 1025444 0 0 7987 4125 1536 2248 11 6 24 60 0
2 0 0 136776 399748 1025444 0 0 971 20 2427 1663 98 1 0 1 0
2 0 0 121404 399748 1025456 0 0 1160 11 2422 1730 96 3 0 1 0
2 0 0 134528 399748 1025460 0 0 1195 17 2399 1695 97 2 0 2 0
3 0 0 134520 399748 1025460 0 0 1325 19 2443 1693 96 1 0 3 0
2 0 0 134536 399748 1025460 0 0 1176 16 2405 1674 99 1 0 0 0
2 0 0 125108 399748 1025460 0 0 1139 11 2418 1647 97 2 0 1 0
2 0 0 134628 399752 1025460 0 0 1235 16 2391 1653 98 1 0 1 0
3 0 0 134644 399752 1025460 0 0 1197 21 2392 1640 97 2 0 1 0
2 0 0 134652 399756 1025460 0 0 1400 16 2433 1670 97 1 0 3 0
2 0 0 125116 399756 1025460 0 0 1008 11 2199 1564 97 2 0 1 0
看來并行的實(shí)現(xiàn)還是有很多的細(xì)節(jié),相比普通的查詢來說更加復(fù)雜,而且消耗的資源更多,這個(gè)也就是在使用并行的時(shí)候需要權(quán)衡的一個(gè)原因。
English »
Afrikaans Albanian Arabic Armenian Azerbaijani Basque Bengali Belarusian Bulgarian Catalan Chinese (Simp) Chinese (Trad) Croatian Czech Danish Dutch English Esperanto Estonian Filipino Finnish French Galician Georgian German Greek Gujarati Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Kannada Korean Lao Latin Latvian Lithuanian Macedonian Malay Maltese Norwegian Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Tamil Telugu Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish
Text-to-speech function is limited to 100 characters
一 磁盤物理結(jié)構(gòu)
(1) 盤片:硬盤的盤體由多個(gè)盤片疊在一起構(gòu)成。
在硬盤出廠時(shí),由硬盤生產(chǎn)商完成了低級(jí)格式化(物理格式化),作用是將空白的盤片(Platter)劃分為一個(gè)個(gè)同圓心、不同半徑的磁道(Track),還將磁道劃分為若干個(gè)扇區(qū)(Sector),每個(gè)扇區(qū)可存儲(chǔ)128×2的N次方(N=0.1.2.3)字節(jié)信息,默認(rèn)每個(gè)扇區(qū)的大小為512字節(jié)。通常使用者無需再進(jìn)行低級(jí)格式化操作。
(2) 磁頭:每張盤片的正反兩面各有一個(gè)磁頭。
(3) 主軸:所有盤片都由主軸電機(jī)帶動(dòng)旋轉(zhuǎn)。
(4) 控制集成電路板:復(fù)雜!上面還有ROM(內(nèi)有軟件系統(tǒng))、Cache等。
二 磁盤如何完成單次IO操作
(1) 尋道
當(dāng)控制器對(duì)磁盤發(fā)出一個(gè)IO操作命令的時(shí)候,磁盤的驅(qū)動(dòng)臂(Actuator Arm)帶動(dòng)磁頭(Head)離開著陸區(qū)(Landing Zone,位于內(nèi)圈沒有數(shù)據(jù)的區(qū)域),
移動(dòng) 到要操作的初始數(shù)據(jù)塊所在的磁道(Track)的正上方,這個(gè)過程被稱為尋道(Seeking),對(duì)應(yīng)消耗的時(shí)間被稱為尋道時(shí)間(Seek Time);
(2) 旋轉(zhuǎn)延遲
找到對(duì)應(yīng)磁道還不能馬上讀取數(shù)據(jù),這時(shí)候磁頭要等到磁盤盤片(Platter)旋轉(zhuǎn)到初始數(shù)據(jù)塊所在的扇區(qū)(Sector)落在讀寫磁頭正下方之后才能開始讀取數(shù)據(jù),在這個(gè)等待盤片旋轉(zhuǎn)到可操作扇區(qū)的過程中消耗的時(shí)間稱為旋轉(zhuǎn)延時(shí)(Rotational Latency);
(3) 數(shù)據(jù)傳送
接下來就隨著盤片的旋轉(zhuǎn),磁頭不斷的讀/寫相應(yīng)的數(shù)據(jù)塊,直到完成這次IO所需要操作的全部數(shù)據(jù),這個(gè)過程稱為數(shù)據(jù)傳送(Data Transfer),對(duì)應(yīng)的時(shí)間稱為傳送時(shí)間(Transfer Time)。完成這三個(gè)步驟之后單次IO操作也就完成了。
根據(jù)磁盤單次IO操作的過程,可以發(fā)現(xiàn):
單次IO時(shí)間 = 尋道時(shí)間 + 旋轉(zhuǎn)延遲 + 傳送時(shí)間
進(jìn)而推算IOPS(IO per second)的公式為:
IOPS = 1000ms/單次IO時(shí)間
三 磁盤IOPS計(jì)算
不同磁盤,它的尋道時(shí)間,旋轉(zhuǎn)延遲,數(shù)據(jù)傳送所需的時(shí)間各是多少?
1. 尋道時(shí)間
考慮到被讀寫的數(shù)據(jù)可能在磁盤的任意一個(gè)磁道,既有可能在磁盤的最內(nèi)圈(尋道時(shí)間最短),也可能在磁盤的最外圈(尋道時(shí)間最長(zhǎng)),所以在計(jì)算中我們只考慮平均尋道時(shí)間。
在購(gòu)買磁盤時(shí),該參數(shù)都有標(biāo)明,目前的SATA/SAS磁盤,按轉(zhuǎn)速不同,尋道時(shí)間不同,不過通常都在10ms以下:
2. 旋轉(zhuǎn)延時(shí)
和尋道一樣,當(dāng)磁頭定位到磁道之后有可能正好在要讀寫扇區(qū)之上,這時(shí)候是不需要額外的延時(shí)就可以立刻讀寫到數(shù)據(jù),但是最壞的情況確實(shí)要磁盤旋轉(zhuǎn)整整一圈之后磁頭才能讀取到數(shù)據(jù),所以這里也考慮的是平均旋轉(zhuǎn)延時(shí),對(duì)于15000rpm的磁盤就是(60s/15000)*(1/2) = 2ms。
3. 傳送時(shí)間
(1) 磁盤傳輸速率
磁盤傳輸速率分兩種:內(nèi)部傳輸速率(Internal Transfer Rate),外部傳輸速率(External Transfer Rate)。
內(nèi)部傳輸速率(Internal Transfer Rate),是指磁頭與硬盤緩存之間的數(shù)據(jù)傳輸速率,簡(jiǎn)單的說就是硬盤磁頭將數(shù)據(jù)從盤片上讀取出來,然后存儲(chǔ)在緩存內(nèi)的速度。
理想的內(nèi)部傳輸速率不存在尋道,旋轉(zhuǎn)延時(shí),就一直在同一個(gè)磁道上讀數(shù)據(jù)并傳到緩存,顯然這是不可能的,因?yàn)閱蝹€(gè)磁道的存儲(chǔ)空間是有限的;
實(shí)際的內(nèi)部傳輸速率包含了尋道和旋轉(zhuǎn)延時(shí),目前家用磁盤,穩(wěn)定的內(nèi)部傳輸速率一般在30MB/s到45MB/s之間(服務(wù)器磁盤,應(yīng)該會(huì)更高)。
外部傳輸速率(External Transfer Rate),是指硬盤緩存和系統(tǒng)總線之間的數(shù)據(jù)傳輸速率,也就是計(jì)算機(jī)通過硬盤接口從緩存中將數(shù)據(jù)讀出交給相應(yīng)的硬盤控制器的速率。
硬盤廠商在硬盤參數(shù)中,通常也會(huì)給出一個(gè)最大傳輸速率,比如現(xiàn)在SATA3.0的6Gbit/s,換算一下就是6*1024/8,768MB/s,通常指的是硬盤接口對(duì)外的最大傳輸速率,當(dāng)然實(shí)際使用中是達(dá)不到這個(gè)值的。
這里計(jì)算IOPS,保守選擇實(shí)際內(nèi)部傳輸速率,以40M/s為例。
(2) 單次IO操作的大小
有了傳送速率,還要知道單次IO操作的大小(IO Chunk Size),才可以算出單次IO的傳送時(shí)間。那么磁盤單次IO的大小是多少?答案是:不確定。
操作系統(tǒng)為了提高 IO的性能而引入了文件系統(tǒng)緩存(File System Cache),系統(tǒng)會(huì)根據(jù)請(qǐng)求數(shù)據(jù)的情況將多個(gè)來自IO的請(qǐng)求先放在緩存里面,然后再一次性的提交給磁盤,也就是說對(duì)于數(shù)據(jù)庫(kù)發(fā)出的多個(gè)8K數(shù)據(jù)塊的讀操作有可能放在一個(gè)磁盤讀IO里就處理了。
還有,有些存儲(chǔ)系統(tǒng)也是提供了緩存(Cache),接收到操作系統(tǒng)的IO請(qǐng)求之后也是會(huì)將多個(gè)操作系統(tǒng)的 IO請(qǐng)求合并成一個(gè)來處理。
不管是操作系統(tǒng)層面的緩存,還是磁盤控制器層面的緩存,目的都只有一個(gè),提高數(shù)據(jù)讀寫的效率。因此每次單獨(dú)的IO操作大小都是不一樣的,它主要取決于系統(tǒng)對(duì)于數(shù)據(jù)讀寫效率的判斷。這里以SQL Server數(shù)據(jù)庫(kù)的數(shù)據(jù)頁(yè)大小為例:8K。
(3) 傳送時(shí)間
傳送時(shí)間 = IO Chunk Size/Internal Transfer Rate = 8k/40M/s = 0.2ms
可以發(fā)現(xiàn):
(3.1) 如果IO Chunk Size大的話,傳送時(shí)間會(huì)變長(zhǎng),單次IO時(shí)間就也變長(zhǎng),從而導(dǎo)致IOPS變小;
(3.2) 機(jī)械磁盤的主要讀寫成本,都花在了尋址時(shí)間上,即:尋道時(shí)間 + 旋轉(zhuǎn)延遲,也就是磁盤臂的擺動(dòng),和磁盤的旋轉(zhuǎn)延遲。
(3.3) 如果粗略的計(jì)算IOPS,可以忽略傳送時(shí)間,1000ms/(尋道時(shí)間 + 旋轉(zhuǎn)延遲)即可。
4. IOPS計(jì)算示例
以15000rpm為例:
(1) 單次IO時(shí)間
單次IO時(shí)間 = 尋道時(shí)間 + 旋轉(zhuǎn)延遲 + 傳送時(shí)間 = 3ms + 2ms + 0.2 ms = 5.2 ms
(2) IOPS
IOPS = 1000ms/單次IO時(shí)間 = 1000ms/5.2ms = 192 (次)
這里計(jì)算的是單塊磁盤的隨機(jī)訪問IOPS。
考慮一種極端的情況,如果磁盤全部為順序訪問,那么就可以忽略:尋道時(shí)間 + 旋轉(zhuǎn)延遲 的時(shí)長(zhǎng),IOPS的計(jì)算公式就變?yōu)椋篒OPS = 1000ms/傳送時(shí)間
IOPS = 1000ms/傳送時(shí)間= 1000ms/0.2ms = 5000 (次)
顯然這種極端的情況太過理想,畢竟每個(gè)磁道的空間是有限的,尋道時(shí)間 + 旋轉(zhuǎn)延遲 時(shí)長(zhǎng)確實(shí)可以減少,不過是無法完全避免的。
四 數(shù)據(jù)庫(kù)中的磁盤讀寫
1. 隨機(jī)訪問和連續(xù)訪問
(1) 隨機(jī)訪問(Random Access)
指的是本次IO所給出的扇區(qū)地址和上次IO給出扇區(qū)地址相差比較大,這樣的話磁頭在兩次IO操作之間需要作比較大的移動(dòng)動(dòng)作才能重新開始讀/寫數(shù)據(jù)。
(2) 連續(xù)訪問(Sequential Access)
相反的,如果當(dāng)次IO給出的扇區(qū)地址與上次IO結(jié)束的扇區(qū)地址一致或者是接近的話,那磁頭就能很快的開始這次IO操作,這樣的多個(gè)IO操作稱為連續(xù)訪問。
(3) 以SQL Server數(shù)據(jù)庫(kù)為例
數(shù)據(jù)文件,SQL Server統(tǒng)一區(qū)上的對(duì)象,是以extent(8*8k)為單位進(jìn)行空間分配的,數(shù)據(jù)存放是很隨機(jī)的,哪個(gè)數(shù)據(jù)頁(yè)有空間,就寫在哪里,除非通過文件組給每個(gè)表預(yù)分配足夠大的、單獨(dú)使用的文件,否則不能保證數(shù)據(jù)的連續(xù)性,通常為隨機(jī)訪問。
另外哪怕聚集索引表,也只是邏輯上的連續(xù),并不是物理上。
日志文件,由于有VLF的存在,日志的讀寫理論上為連續(xù)訪問,但如果日志文件設(shè)置為自動(dòng)增長(zhǎng),且增量不大,VLF就會(huì)很多很小,那么就也并不是嚴(yán)格的連續(xù)訪問了。
2. 順序IO和并發(fā)IO
(1) 順序IO模式(Queue Mode)
磁盤控制器可能會(huì)一次對(duì)磁盤組發(fā)出一連串的IO命令,如果磁盤組一次只能執(zhí)行一個(gè)IO命令,稱為順序IO;
(2) 并發(fā)IO模式(Burst Mode)
當(dāng)磁盤組能同時(shí)執(zhí)行多個(gè)IO命令時(shí),稱為并發(fā)IO。并發(fā)IO只能發(fā)生在由多個(gè)磁盤組成的磁盤組上,單塊磁盤只能一次處理一個(gè)IO命令。
(3) 以SQL Server數(shù)據(jù)庫(kù)為例
有的時(shí)候,盡管磁盤的IOPS(Disk Transfers/sec)還沒有太大,但是發(fā)現(xiàn)數(shù)據(jù)庫(kù)出現(xiàn)IO等待,為什么?通常是因?yàn)橛辛舜疟P請(qǐng)求隊(duì)列,有過多的IO請(qǐng)求堆積。
磁盤的請(qǐng)求隊(duì)列和繁忙程度,通過以下性能計(jì)數(shù)器查看:
LogicalDisk/Avg.Disk Queue Length
LogicalDisk/Current Disk Queue Length
LogicalDisk/%Disk Time
這種情況下,可以做的是:
(1) 簡(jiǎn)化業(yè)務(wù)邏輯,減少IO請(qǐng)求數(shù);
(2) 同一個(gè)實(shí)例下的多個(gè)用戶數(shù)據(jù)庫(kù),遷移到不同實(shí)例下;
(3) 同一個(gè)數(shù)據(jù)庫(kù)的日志、數(shù)據(jù)文件,分離到不同的存儲(chǔ)單元;
(4) 借助HA策略,做讀寫操作的分離。
3. IOPS和吞吐量(throughput)
(1) IOPS
IOPS即每秒進(jìn)行讀寫(I/O)操作的次數(shù)。在計(jì)算傳送時(shí)間時(shí),有提到:如果IO Chunk Size大的話,那么IOPS會(huì)變小,假設(shè)以100M為單位讀寫數(shù)據(jù),那么IOPS就會(huì)很小。
(2) 吞吐量(throughput)
吞吐量指每秒可以讀寫的字節(jié)數(shù)。同樣假設(shè)以100M為單位讀寫數(shù)據(jù),盡管IOPS很小,但是每秒讀寫了N*100M的數(shù)據(jù),吞吐量并不小。
(3) 以SQL Server數(shù)據(jù)庫(kù)為例
對(duì)于OLTP的系統(tǒng),經(jīng)常讀寫小塊數(shù)據(jù),多為隨機(jī)訪問,用IOPS來衡量讀寫性能;
對(duì)于數(shù)據(jù)倉(cāng)庫(kù),日志文件,經(jīng)常讀寫大塊數(shù)據(jù),多為順序訪問,用吞吐量來衡量讀寫性能。
磁盤當(dāng)前的IOPS,通過以下性能計(jì)數(shù)器查看:
LogicalDisk/Disk Transfers/sec
LogicalDisk/Disk Reads/sec
LogicalDisk/Disk Writes/sec
磁盤當(dāng)前的吞吐量,通過以下性能計(jì)數(shù)器查看:
LogicalDisk/Disk Bytes/sec
LogicalDisk/Disk Read Bytes/sec
LogicalDisk/Disk Write Bytes/sec
English »
Afrikaans Albanian Arabic Armenian Azerbaijani Basque Bengali Belarusian Bulgarian Catalan Chinese (Simp) Chinese (Trad) Croatian Czech Danish Dutch English Esperanto Estonian Filipino Finnish French Galician Georgian German Greek Gujarati Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Kannada Korean Lao Latin Latvian Lithuanian Macedonian Malay Maltese Norwegian Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Tamil Telugu Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish
Text-to-speech function is limited to 100 characters
============問題描述============
在
數(shù)據(jù)庫(kù) 中存放用戶發(fā)帖的信息,利用下面的程序得到該用戶發(fā)帖的數(shù)量。可是UserUtils的值一直是1,這是怎么回事?
ResultSet res = sqlConn
.executeQuery("select count(*) from" + username
+ "_message");
while (res.next()) {
UserUtils.flag = res.getInt(1);
System.out.println("userUtils = " + UserUtils.flag);
}
============解決方案1============
from這后面加個(gè)空格吧
============解決方案2============
select count(*) from后面少了一個(gè)空格樣。
English »
Afrikaans Albanian Arabic Armenian Azerbaijani Basque Bengali Belarusian Bulgarian Catalan Chinese (Simp) Chinese (Trad) Croatian Czech Danish Dutch English Esperanto Estonian Filipino Finnish French Galician Georgian German Greek Gujarati Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Kannada Korean Lao Latin Latvian Lithuanian Macedonian Malay Maltese Norwegian Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Tamil Telugu Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish
Text-to-speech function is limited to 100 characters
UPDATE or DELETE whitout where…
table was DROPPed accidentally…
INNODB was corrupt…
entire datacenter loses power…
從數(shù)據(jù)安全的角度來說,服務(wù)器磁盤都會(huì)做raid,
MySQL 本身也有主從、drbd等容災(zāi)機(jī)制,但它們都無法完全取代備份。容災(zāi)和高可用能幫我們有效的應(yīng)對(duì)物理的、硬件的、機(jī)械的故障,而對(duì)我們犯下的邏輯錯(cuò)誤卻無能為力。每一種邏輯錯(cuò)誤發(fā)生的概率都極低,但是當(dāng)多種可能性疊加的時(shí)候,小概率事件就放大成很大的安全隱患,這時(shí)候備份的必要性就凸顯了。那么在眾多的MySQL備份方式中,哪一種才是適合我們的呢?
常見的備份方式
MySQL本身為我們提供了mysqldump、mysqlbinlog遠(yuǎn)程備份工具,percona也為我們提供了強(qiáng)大的Xtrabackup,加上開源的mydumper,還有基于主從同步的延遲備份、從庫(kù)冷備等方式,以及基于文件系統(tǒng)快照的備份,其實(shí)選擇已經(jīng)多到眼花繚亂。而備份本身是為了恢復(fù),所以能夠讓我們?cè)诔霈F(xiàn)故障后迅速、準(zhǔn)確恢復(fù)的備份方式,就是最適合我們的,當(dāng)然,同時(shí)能夠省錢、省事,那就非常完美。下面就我理解的幾種備份工具進(jìn)行一些比較,探討下它們各自的適用場(chǎng)景。
1. mysqldump & mydumper
mysqldump是最簡(jiǎn)單的邏輯備份方式。在備份myisam表的時(shí)候,如果要得到一致的數(shù)據(jù),就需要鎖表,簡(jiǎn)單而粗暴。而在備份innodb表的時(shí)候,加上–master-data=1 –single-transaction 選項(xiàng),在事務(wù)開始時(shí)刻,記錄下binlog pos點(diǎn),然后利用mvcc來獲取一致的數(shù)據(jù),由于是一個(gè)長(zhǎng)事務(wù),在寫入和更新量很大的數(shù)據(jù)庫(kù)上,將產(chǎn)生非常多的undo,顯著影響性能,所以要慎用。
優(yōu)點(diǎn):簡(jiǎn)單,可針對(duì)單表備份,在全量導(dǎo)出表結(jié)構(gòu)的時(shí)候尤其有用。
缺點(diǎn):簡(jiǎn)單粗暴,單線程,備份慢而且恢復(fù)慢,跨IDC有可能遇到時(shí)區(qū)問題。
mydumper是mysqldump的加強(qiáng)版。相比mysqldump:
內(nèi)置支持壓縮,可以節(jié)省2-4倍的存儲(chǔ)空間。
支持并行備份和恢復(fù),因此速度比mysqldump快很多,但是由于是邏輯備份,仍不是很快。
2. 基于文件系統(tǒng)的快照
基于文件系統(tǒng)的快照,是物理備份的一種。在備份前需要進(jìn)行一些復(fù)雜的設(shè)置,在備份開始時(shí)刻獲得快照并記錄下binlog pos點(diǎn),然后采用類似copy-on-write的方式,把快照進(jìn)行轉(zhuǎn)儲(chǔ)。轉(zhuǎn)儲(chǔ)快照本身會(huì)消耗一定的IO資源,而且在寫入壓力較大的實(shí)例上,保存被更改數(shù)據(jù)塊的前印象也會(huì)消耗IO,最終表現(xiàn)為整體性能的下降。而且服務(wù)器還要為copy-on-write快照預(yù)留較多的磁盤空間,這本身對(duì)資源也是一種浪費(fèi)。因此這種備份方式我們使用的不多。
English »
Afrikaans Albanian Arabic Armenian Azerbaijani Basque Bengali Belarusian Bulgarian Catalan Chinese (Simp) Chinese (Trad) Croatian Czech Danish Dutch English Esperanto Estonian Filipino Finnish French Galician Georgian German Greek Gujarati Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Kannada Korean Lao Latin Latvian Lithuanian Macedonian Malay Maltese Norwegian Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Tamil Telugu Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish
Text-to-speech function is limited to 100 characters
1、觸發(fā)器使 Session 的緩存中的持久化對(duì)象與數(shù)據(jù)庫(kù)中對(duì)應(yīng)的數(shù)據(jù)不一致:觸發(fā)器運(yùn)行在數(shù)據(jù)庫(kù)中, 它執(zhí)行的操作對(duì) Session 是透明的 Session 的
解決方案: 在執(zhí)行完 Session 的相關(guān)操作后, 立即調(diào)用 Session 的 flush() 和 refresh() 方法, 迫使 Session 的緩存與數(shù)據(jù)庫(kù)同步(refresh() 方法重新從數(shù)據(jù)庫(kù)中加載對(duì)
象)
2、update() 方法盲目地激發(fā)觸發(fā)器: 無論游離對(duì)象的屬性是否發(fā)生變化, 都會(huì)執(zhí)行 update 語句, 而 update 語句會(huì)激發(fā)數(shù)據(jù)庫(kù)中相應(yīng)的觸發(fā)器
解決方案:在映射文件的的 <class> 元素中設(shè)置 select-before-update 屬性: 當(dāng) Session 的 update 或 saveOrUpdate() 方法更新一個(gè)游離對(duì)象時(shí), 會(huì)先執(zhí)行 Select 語句, 獲得當(dāng)前游離對(duì)象在數(shù)據(jù)庫(kù)中的最新數(shù)據(jù), 只有在不一致的情況下才會(huì)執(zhí)行 update 語句(沒有用到觸發(fā)器的時(shí)候一般的情況下最好不要設(shè)置,因?yàn)闀?huì)降低效率的)
English »
Afrikaans Albanian Arabic Armenian Azerbaijani Basque Bengali Belarusian Bulgarian Catalan Chinese (Simp) Chinese (Trad) Croatian Czech Danish Dutch English Esperanto Estonian Filipino Finnish French Galician Georgian German Greek Gujarati Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Kannada Korean Lao Latin Latvian Lithuanian Macedonian Malay Maltese Norwegian Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Tamil Telugu Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish
Text-to-speech function is limited to 100 characters
Java 應(yīng)用中拋出的空指針異常是解決空指針的最好方式,也是寫出能順利
工作 的健壯程序的關(guān)鍵。俗話說“預(yù)防勝于治療”,對(duì)于這么令人討厭的空指針異常,這句話也是成立的。值得慶幸的是運(yùn)用一些防御性的編碼技巧,跟蹤應(yīng)用中多個(gè)部分之間的聯(lián)系,你可以將Java中的空指針異常控制在一個(gè)很好的水平上。順便說一句,這是Javarevisited上的第二個(gè)空指針異常的帖子。在上個(gè)帖子中我們討論了Java中導(dǎo)致空指針異常的常見原因,而在本教程中我們將會(huì)
學(xué)習(xí) 一些Java的編程技巧和最佳實(shí)踐。這些技巧可以幫助你避免Java中的空指針異常。遵從這些技巧同樣可以減少Java代碼中到處都有的非空檢查的數(shù)量。作為一個(gè)有經(jīng)驗(yàn)的Java程序員,你可能已經(jīng)知道其中的一部分技巧并且應(yīng)用在你的項(xiàng)目中。但對(duì)于新手和中級(jí)開發(fā)人員來說,這將是很值得學(xué)習(xí)的。順便說一句,如果你知道其它的避免空指針異常和減少空指針檢查的Java技巧,請(qǐng)和我們分享。
這些都是簡(jiǎn)單的技巧,很容易應(yīng)用,但是對(duì)代碼質(zhì)量和健壯性有顯著影響。根據(jù)我的經(jīng)驗(yàn),只有第一個(gè)技巧可以顯著改善代碼質(zhì)量。如我之前所講,如果你知道任何避免空指針異常和減少空指針檢查的Java技巧,你可以通過評(píng)論本文來和分享。
1) 從已知的String對(duì)象中調(diào)用equals()和equalsIgnoreCase()方法,而非未知對(duì)象。
總是從已知的非空String對(duì)象中調(diào)用equals()方法。因?yàn)閑quals()方法是對(duì)稱的,調(diào)用a.equals(b)和調(diào)用b.equals(a)是完全相同的,這也是為什么程序員對(duì)于對(duì)象a和b這么不上心。如果調(diào)用者是空指針,這種調(diào)用可能導(dǎo)致一個(gè)空指針異常
Object unknownObject = null;
//錯(cuò)誤方式 – 可能導(dǎo)致 NullPointerException
if(unknownObject.equals("knownObject")){
System.err.println("This may result in NullPointerException if unknownObject is null");
}
//正確方式 - 即便 unknownObject是null也能避免NullPointerException
if("knownObject".equals(unknownObject)){
System.err.println("better coding avoided NullPointerException");
}
這是避免空指針異常最簡(jiǎn)單的Java技巧,但能夠?qū)е戮薮蟮母倪M(jìn),因?yàn)閑quals()是一個(gè)常見方法。
2) 當(dāng)valueOf()和toString()返回相同的結(jié)果時(shí),寧愿使用前者。
因?yàn)檎{(diào)用null對(duì)象的toString()會(huì)拋出空指針異常,如果我們能夠使用valueOf()獲得相同的值,那寧愿使用valueOf(),傳遞一個(gè)null給valueOf()將會(huì)返回“null”,尤其是在那些包裝類,像Integer、Float、Double和BigDecimal。
BigDecimal bd = getPrice();
System.out.println(String.valueOf(bd)); //不會(huì)拋出空指針異常
System.out.println(bd.toString()); //拋出 "Exception in thread "main" java.lang.NullPointerException"
3) 使用null安全的方法和庫(kù) 有很多開源庫(kù)已經(jīng)為您做了繁重的空指針檢查工作。其中最常用的一個(gè)的是Apache commons 中的StringUtils。你可以使用StringUtils.isBlank(),isNumeric(),isWhiteSpace()以及其他的工具方法而不用擔(dān)心空指針異常。
//StringUtils方法是空指針安全的,他們不會(huì)拋出空指針異常
System.out.println(StringUtils.isEmpty(null));
System.out.println(StringUtils.isBlank(null));
System.out.println(StringUtils.isNumeric(null));
System.out.println(StringUtils.isAllUpperCase(null));
Output:
true
true
false
false
但是在做出結(jié)論之前,不要忘記閱讀空指針方法的類的文檔。這是另一個(gè)不需要下大功夫就能得到很大改進(jìn)的Java最佳實(shí)踐。
English »
Afrikaans Albanian Arabic Armenian Azerbaijani Basque Bengali Belarusian Bulgarian Catalan Chinese (Simp) Chinese (Trad) Croatian Czech Danish Dutch English Esperanto Estonian Filipino Finnish French Galician Georgian German Greek Gujarati Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Kannada Korean Lao Latin Latvian Lithuanian Macedonian Malay Maltese Norwegian Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Tamil Telugu Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish
Text-to-speech function is limited to 100 characters
最近做程序,時(shí)不時(shí)需要自己去手動(dòng)將sql語句直接寫入到
Java 代碼中,寫入sql語句時(shí),需要注意幾個(gè)小問題。
先看我之前寫的幾句簡(jiǎn)單的sql語句,自以為沒有問題,但是編譯直接報(bào)錯(cuò)。
String str = "insert into XXX(a,b,c) values ('"a.getA()"','"a.getB()"','"a.getC()"');";
研究了半天發(fā)現(xiàn)應(yīng)該是連接字符串問題,第一次修改過后將賦值字段前后加“+”號(hào)來完成sql語句。改正后代碼如下
String str = "insert into XXX(a,b,c) values ('"+a.getA()+"','"+a.getB()+"','"+a.getC()+"');";
原來在
數(shù)據(jù)庫(kù) 中給字段動(dòng)態(tài)賦值需要以‘“+···+”’的方式來完成。好的,編譯后成功,將運(yùn)行的str的結(jié)果值放入sql數(shù)據(jù)庫(kù)中
測(cè)試 ,沒有問題,自以為一切ok了,結(jié)果運(yùn)行時(shí)再次報(bào)錯(cuò)。這把自己困擾住了,反復(fù)測(cè)試,在數(shù)據(jù)庫(kù)中用sql語句來對(duì)比,沒有問題啊,現(xiàn)將我最后成功的代碼放上來,大家看看有沒有什么不同。
String str = "insert into XXX(a,b,c) values ('"+a.getA()+"','"+a.getB()+"','"+a.getC()+"')";
沒錯(cuò),就是最后的分號(hào),原來在java語句中不能講分號(hào)加入到普通的sql語句中,雖然在數(shù)據(jù)庫(kù)中沒有報(bào)錯(cuò),但是在java中一定還是要注意這種小問題的。
English »
Afrikaans Albanian Arabic Armenian Azerbaijani Basque Bengali Belarusian Bulgarian Catalan Chinese (Simp) Chinese (Trad) Croatian Czech Danish Dutch English Esperanto Estonian Filipino Finnish French Galician Georgian German Greek Gujarati Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Kannada Korean Lao Latin Latvian Lithuanian Macedonian Malay Maltese Norwegian Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Tamil Telugu Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish
Text-to-speech function is limited to 100 characters
今天在優(yōu)化一個(gè)功能的時(shí)候遇到了instr與substr函數(shù),之前沒有接觸過這兩個(gè)函數(shù),但是今天無意中用到,一查才發(fā)現(xiàn),真是實(shí)用的一對(duì)兄弟啊。
先來說說substr函數(shù),這個(gè)函數(shù)返回的是字符串的一部分。
substr(string,start,length)
其中string參數(shù)為必須參數(shù),要截取的字符串內(nèi)容。
start為必須參數(shù),為起始的位置,可以為正數(shù)也可以為負(fù)數(shù),正數(shù)的話代表從在字符串的指定位置開始;負(fù)數(shù)代表從字符串結(jié)尾的指定位置開始;0代表在字符串中的第一個(gè)字符處開始。
length不是必須參數(shù),為截取的長(zhǎng)度,正數(shù)代表從 start 參數(shù)所在的位置向后返回字符個(gè)數(shù);負(fù)數(shù)代表從字符串末端指定位置向前返回字符個(gè)數(shù)。
舉個(gè)例子:
substr("Hello World!",2,1)返回的是e
substr("Hello World!",2)返回的是ello World!
substr("Hello World!",-2,1)返回的是d
substr("Hello World!",-2,-1)返回的是d!
instr( string1, string2, start_position,nth_appearance ) 函數(shù)返回要截取的字符串在源字符串中的位置。
string1源字符串,要在此字符串中查找。
string2要在string1中查找的字符串 。
start_position代表開始的位置。
nth_appearance代表要查找第幾次出現(xiàn)的string2. 此參數(shù)可選,如果省略,默認(rèn)為 1.如果為負(fù)數(shù)系統(tǒng)會(huì)報(bào)錯(cuò)。
舉個(gè)例子:
instr("Hello World!","o")返回的是5
instr("Hello World!","o",1,2)返回的是8。解釋一下,這句話代表"o"從字符串第一個(gè)位置開始查詢,第二個(gè)“o”出現(xiàn)的位置。
很有用的兩個(gè)函數(shù)呢
English »
Afrikaans Albanian Arabic Armenian Azerbaijani Basque Bengali Belarusian Bulgarian Catalan Chinese (Simp) Chinese (Trad) Croatian Czech Danish Dutch English Esperanto Estonian Filipino Finnish French Galician Georgian German Greek Gujarati Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Kannada Korean Lao Latin Latvian Lithuanian Macedonian Malay Maltese Norwegian Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Tamil Telugu Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish
Text-to-speech function is limited to 100 characters