Linux環(huán)境下Oracle大頁配置全過程
一、大頁內(nèi)存介紹?
(一)概念?
大頁內(nèi)存,是指使用比系統(tǒng)默認(rèn)頁面更大的內(nèi)存頁面來管理內(nèi)存。在傳統(tǒng)的內(nèi)存管理模式下,操作系統(tǒng)使用較小的頁面(例如 4KB)來管理內(nèi)存,而大頁內(nèi)存通常提供 2MB 甚至 1GB 的頁面大小。?
對于大的SGA大小,HugePages可以在虛擬內(nèi)存管理方面提供實(shí)質(zhì)性的好處。如果沒有HugePages, SGA的內(nèi)存將被劃分為4K頁面,這些頁面必須由Linux內(nèi)核管理。使用HugePages,頁面大小增加到2MB(如果硬件支持,可以配置為1G),從而減少了內(nèi)核要管理的頁面總數(shù),從而減少了在內(nèi)存中保存頁面表所需的內(nèi)存量。除了這些更改之外,與HugePages關(guān)聯(lián)的內(nèi)存不能交換出去,這迫使SGA保持內(nèi)存駐留。內(nèi)存的節(jié)省和頁面管理的工作量使得在x86-64架構(gòu)上運(yùn)行的Oracle系統(tǒng)幾乎必須使用HugePages。
(二)優(yōu)勢?
- 減少頁表項(xiàng)數(shù)量:由于大頁內(nèi)存頁面尺寸更大,同樣大小的內(nèi)存使用大頁時(shí)所需的頁表項(xiàng)數(shù)量會(huì)大幅減少。這可以降低 CPU 在地址轉(zhuǎn)換時(shí)對頁表的訪問次數(shù),從而提高內(nèi)存訪問效率。?
- 降低 TLB(Translation Lookaside Buffer,轉(zhuǎn)換后援緩沖器)壓力:TLB 用于緩存頁表項(xiàng),以加快內(nèi)存地址轉(zhuǎn)換速度。大頁內(nèi)存減少了頁表項(xiàng)數(shù)量,進(jìn)而降低了 TLB 的負(fù)載,減少 TLB 未命中的情況,提升內(nèi)存訪問性能。?
- 提升應(yīng)用程序性能:對于像 Oracle 這樣的大型數(shù)據(jù)庫管理系統(tǒng),頻繁的內(nèi)存操作和數(shù)據(jù)讀寫對內(nèi)存性能要求極高。大頁內(nèi)存能夠提供更高效的內(nèi)存訪問,減少內(nèi)存碎片,從而顯著提升 Oracle 數(shù)據(jù)庫的運(yùn)行性能。?
(三)在 Oracle 數(shù)據(jù)庫中的作用
Oracle 數(shù)據(jù)庫的 SGA(System Global Area,系統(tǒng)全局區(qū))是數(shù)據(jù)庫運(yùn)行時(shí)最重要的內(nèi)存區(qū)域,用于存儲(chǔ)數(shù)據(jù)庫實(shí)例的數(shù)據(jù)和控制信息。將 SGA 放置在大頁內(nèi)存中,可以充分利用大頁內(nèi)存的優(yōu)勢,使 SGA 中的數(shù)據(jù)訪問更加快速和高效,減少內(nèi)存爭用,為數(shù)據(jù)庫的穩(wěn)定運(yùn)行和高性能表現(xiàn)提供有力保障。?
一個(gè)大的SGA并不意味著如果不使用HugePages就會(huì)出現(xiàn)問題。通常,大型SGA和大量數(shù)據(jù)庫連接的組合會(huì)導(dǎo)致問題。要確定當(dāng)前使用多少內(nèi)存來支持頁表,請?jiān)诜?wù)器處于正常/重載狀態(tài)時(shí)運(yùn)行以下命令。
# grep PageTables /proc/meminfo PageTables: 1244880 kB
注意:自動(dòng)內(nèi)存管理(Automatic Memory Management, AMM)與Linux HugePages不兼容,所以除了ASM實(shí)例和小型不重要的數(shù)據(jù)庫之外,在Linux上運(yùn)行的真實(shí)數(shù)據(jù)庫上可能不需要AMM。相反,應(yīng)該使用自動(dòng)共享內(nèi)存管理和自動(dòng)PGA管理,因?yàn)樗鼈兣cHugePages兼容
二、配置大頁
運(yùn)行以下命令確定當(dāng)前HugePage的使用情況。在Oracle Linux 8上,默認(rèn)的HugePage大小是2MB。從下面的輸出中可以看到,默認(rèn)情況下沒有定義HugePages。
$ grep Huge /proc/meminfo AnonHugePages: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB
根據(jù)SGA的大小,您可能希望將Hugepagesize的值增加到1G。
用以下內(nèi)容創(chuàng)建一個(gè)名為“hugepages_setting.sh”的文件。
#!/bin/bash
#
# hugepages_setting.sh
#
# Linux bash script to compute values for the
# recommended HugePages/HugeTLB configuration
#
# Note: This script does calculation for all shared memory
# segments available when the script is run, no matter it
# is an Oracle RDBMS shared memory segment or not.
# Check for the kernel version
KERN=`uname -r | awk -F. '{ printf("%d.%d\n",$1,$2); }'`
# Find out the HugePage size
HPG_SZ=`grep Hugepagesize /proc/meminfo | awk {'print $2'}`
# Start from 1 pages to be on the safe side and guarantee 1 free HugePage
NUM_PG=1
# Cumulative number of pages required to handle the running shared memory segments
for SEG_BYTES in `ipcs -m | awk {'print $5'} | grep "[0-9][0-9]*"`
do
MIN_PG=`echo "$SEG_BYTES/($HPG_SZ*1024)" | bc -q`
if [ $MIN_PG -gt 0 ]; then
NUM_PG=`echo "$NUM_PG+$MIN_PG+1" | bc -q`
fi
done
# Finish with results
case $KERN in
'2.4') HUGETLB_POOL=`echo "$NUM_PG*$HPG_SZ/1024" | bc -q`;
echo "Recommended setting: vm.hugetlb_pool = $HUGETLB_POOL" ;;
'2.6' | '3.8' | '3.10' | '4.1' | '4.14' ) echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
*) echo "Unrecognized kernel version $KERN. Exiting." ;;
esac
# End使文件可執(zhí)行。
$ chmod u+x hugepages_setting.sh
確保所有Oracle服務(wù)在服務(wù)器上正常運(yùn)行,然后運(yùn)行腳本并記錄推薦的“vm.nr_hugepages”價(jià)值。
$ ./hugepages_setting.sh Recommended setting: vm.nr_hugepages = 305
以“root”用戶身份編輯“/etc/sysctl.conf”文件,添加以下條目,并根據(jù)腳本的輸出進(jìn)行調(diào)整。您應(yīng)該將值設(shè)置為大于或等于腳本顯示的值。您只需要 1 或 2 個(gè)備用頁。
vm.nr_hugepages=306
以“root”用戶身份運(yùn)行以下命令。
# sysctl -p
或者,編輯“/etc/grub.conf”文件,將“hugepages=306”添加到默認(rèn)內(nèi)核的內(nèi)核行末尾,然后重新啟動(dòng)。
您現(xiàn)在可以看到 HugePages 已創(chuàng)建,但當(dāng)前尚未使用。
$ grep Huge /proc/meminfo AnonHugePages: 0 kB HugePages_Total: 306 HugePages_Free: 306 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB
將以下條目添加到“/etc/security/limits.conf”腳本或“/etc/security/limits.d/99-grid-oracle-limits.conf”腳本中,其中設(shè)置至少為HugePages 分配(以 KB 為單位)(HugePages * Hugepagesize)。在這種情況下,該值為 306*2048=626688。
* soft memlock 626688 * hard memlock 626688
檢查是否未為數(shù)據(jù)庫設(shè)置 MEMORY_TARGET 參數(shù),而是使用 SGA_TARGET 和 PGA_AGGREGATE_TARGET 參數(shù)。
SQL> show parameter target NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ archive_lag_target integer 0 db_flashback_retention_target integer 1440 fast_start_io_target integer 0 fast_start_mttr_target integer 0 memory_max_target big integer 0 memory_target big integer 0 parallel_servers_target integer 16 pga_aggregate_target big integer 200M sga_target big integer 600M
根據(jù)需要重啟服務(wù)器并重啟數(shù)據(jù)庫服務(wù)。
再次檢查HugePages信息。
$ grep Huge /proc/meminfo AnonHugePages: 0 kB HugePages_Total: 306 HugePages_Free: 98 HugePages_Rsvd: 93 HugePages_Surp: 0 Hugepagesize: 2048 kB
您可以看到 HugePages 現(xiàn)在正在被使用。
三、強(qiáng)制ORACLE使用大頁 (USE_LARGE_PAGES)
正確調(diào)整 HugePages 的數(shù)量非常重要,因?yàn)樵?11.2.0.3 之前,如果整個(gè) SGA 不適合可用的 HugePages,實(shí)例將在不使用任何 HugePages 的情況下啟動(dòng)。從11.2.0.3開始,SGA部分可以運(yùn)行在HugePages中,部分不能運(yùn)行,所以這個(gè)問題的影響不是很大。不正確的尺寸可能不易被發(fā)現(xiàn)。數(shù)據(jù)庫的更高版本在啟動(dòng)期間在警報(bào)日志中顯示“大頁信息”部分。
****************** Large Pages Information ***************** Total Shared Global Region in Large Pages = 602 MB (100%) Large Pages used by this instance: 301 (602 MB) Large Pages unused system wide = 5 (10 MB) (alloc incr 4096 KB) Large Pages configured system wide = 306 (612 MB) Large Page size = 2048 KB ***********************************************************
如果您運(yùn)行的是 Oracle 11.2.0.2 或更高版本,則可以將 USE_LARGE_PAGES 初始化參數(shù)設(shè)置為“only”,這樣數(shù)據(jù)庫在沒有大頁支持的情況下將無法啟動(dòng)。
ALTER SYSTEM SET use_large_pages=only SCOPE=SPFILE; SHUTDOWN IMMEDIATE; STARTUP;
啟動(dòng)時(shí),警報(bào)日志中的“大頁面信息”反映了此參數(shù)的使用。
****************** Large Pages Information ***************** Parameter use_large_pages = ONLY Total Shared Global Region in Large Pages = 602 MB (100%) Large Pages used by this instance: 301 (602 MB) Large Pages unused system wide = 5 (10 MB) (alloc incr 4096 KB) Large Pages configured system wide = 306 (612 MB) Large Page size = 2048 KB ***********************************************************
當(dāng)沒有足夠的 HugePages 來容納 SGA 時(shí)嘗試啟動(dòng)數(shù)據(jù)庫現(xiàn)在將返回以下錯(cuò)誤。
SQL> STARTUP ORA-27137: unable to allocate large pages to create a shared memory segment Linux-x86_64 Error: 12: Cannot allocate memory SQL>
警報(bào)日志輸出的“大頁信息”部分描述了啟動(dòng)失敗以及要采取的適當(dāng)操作。
****************** Large Pages Information ***************** Parameter use_large_pages = ONLY Large Pages unused system wide = 0 (0 KB) (alloc incr 4096 KB) Large Pages configured system wide = 0 (0 KB) Large Page size = 2048 KB ERROR: Failed to allocate shared global region with large pages, unix errno = 12. Aborting Instance startup. ORA-27137: unable to allocate Large Pages to create a shared memory segment ACTION: Total Shared Global Region size is 608 MB. Increase the number of unused large pages to atleast 304 (608 MB) to allocate 100% Shared Global Region with Large Pages. ***********************************************************
四、禁止透明大頁
從 RHEL6/OL6 開始,默認(rèn)實(shí)現(xiàn)并啟用透明大頁。它們旨在通過允許“khugpaged”內(nèi)核線程動(dòng)態(tài)分配 HugePages 來改進(jìn)內(nèi)存管理,而不是像傳統(tǒng)的 HugePages 那樣在啟動(dòng)時(shí)分配。這聽起來是個(gè)好主意,但不幸的是,透明大頁不能很好地與 Oracle 數(shù)據(jù)庫配合使用,并且與 RAC 安裝中的節(jié)點(diǎn)重新啟動(dòng)以及單實(shí)例和 RAC 安裝中的性能問題相關(guān)。因此,Oracle 建議在運(yùn)行 Oracle 數(shù)據(jù)庫的所有服務(wù)器上禁用透明大頁。
五、大頁性能測試
以下是一個(gè)實(shí)驗(yàn)過程,用于證明 Oracle 在 Linux 上開啟大頁內(nèi)存配置后能獲得明顯的性能提升。這個(gè)實(shí)驗(yàn)設(shè)計(jì)包含了測試環(huán)境準(zhǔn)備、測試方案設(shè)計(jì)、測試執(zhí)行和結(jié)果分析等關(guān)鍵環(huán)節(jié)。
(一)腳本analyze-results.sh
#!/bin/bash
# Oracle大頁內(nèi)存性能測試 - 結(jié)果分析腳本
# 檢查參數(shù)
if [ -z "$1" ] || [ -z "$2" ]; then
echo "用法: $0 <非大頁測試結(jié)果目錄> <大頁測試結(jié)果目錄>"
exit 1
fi
# 定義常量
NON_HUGEPAGES_DIR=$1
HUGEPAGES_DIR=$2
ANALYSIS_DIR="$HOME/hugepages_analysis_$(date +%Y%m%d_%H%M%S)"
RESULT_FILE="$ANALYSIS_DIR/comparison_results.txt"
# 創(chuàng)建分析目錄
mkdir -p $ANALYSIS_DIR
# 記錄結(jié)果函數(shù)
record_result() {
echo "$1" >> $RESULT_FILE
echo "$1"
}
# 分析測試結(jié)果
analyze_test_results() {
local test_type=$1
local non_hugepages_files=$(find $NON_HUGEPAGES_DIR -name "${test_type}*.txt" | sort)
local hugepages_files=$(find $HUGEPAGES_DIR -name "${test_type}*.txt" | sort)
record_result "=== 測試類型: $test_type ==="
record_result ""
local non_hugepages_total_time=0
local non_hugepages_count=0
local hugepages_total_time=0
local hugepages_count=0
# 計(jì)算非大頁測試的平均時(shí)間
record_result "非大頁測試結(jié)果:"
for file in $non_hugepages_files; do
# 提取real時(shí)間
real_time=$(grep "real" "$file" | tail -1 | awk '{print $2}')
# 轉(zhuǎn)換為秒
minutes=$(echo $real_time | cut -d'm' -f1)
seconds=$(echo $real_time | cut -d'm' -f2 | cut -d's' -f1)
total_seconds=$(echo "scale=2; $minutes * 60 + $seconds" | bc)
record_result " 文件: $(basename $file), 執(zhí)行時(shí)間: ${total_seconds}秒"
non_hugepages_total_time=$(echo "scale=2; $non_hugepages_total_time + $total_seconds" | bc)
((non_hugepages_count++))
done
if [ $non_hugepages_count -gt 0 ]; then
non_hugepages_avg_time=$(echo "scale=2; $non_hugepages_total_time / $non_hugepages_count" | bc)
record_result " 平均執(zhí)行時(shí)間: ${non_hugepages_avg_time}秒"
else
record_result " 未找到非大頁測試結(jié)果"
non_hugepages_avg_time=0
fi
record_result ""
# 計(jì)算大頁測試的平均時(shí)間
record_result "大頁測試結(jié)果:"
for file in $hugepages_files; do
# 提取real時(shí)間
real_time=$(grep "real" "$file" | tail -1 | awk '{print $2}')
# 轉(zhuǎn)換為秒
minutes=$(echo $real_time | cut -d'm' -f1)
seconds=$(echo $real_time | cut -d'm' -f2 | cut -d's' -f1)
total_seconds=$(echo "scale=2; $minutes * 60 + $seconds" | bc)
record_result " 文件: $(basename $file), 執(zhí)行時(shí)間: ${total_seconds}秒"
hugepages_total_time=$(echo "scale=2; $hugepages_total_time + $total_seconds" | bc)
((hugepages_count++))
done
if [ $hugepages_count -gt 0 ]; then
hugepages_avg_time=$(echo "scale=2; $hugepages_total_time / $hugepages_count" | bc)
record_result " 平均執(zhí)行時(shí)間: ${hugepages_avg_time}秒"
else
record_result " 未找到大頁測試結(jié)果"
hugepages_avg_time=0
fi
record_result ""
# 計(jì)算性能提升百分比
if [ $non_hugepages_avg_time -gt 0 ] && [ $hugepages_avg_time -gt 0 ]; then
improvement=$(echo "scale=2; (1 - $hugepages_avg_time / $non_hugepages_avg_time) * 100" | bc)
record_result "性能提升: ${improvement}%"
else
record_result "無法計(jì)算性能提升百分比"
fi
record_result "========================================"
record_result ""
}
# 主函數(shù)
record_result "Oracle大頁內(nèi)存性能測試對比分析"
record_result "測試日期: $(date)"
record_result "非大頁測試結(jié)果目錄: $NON_HUGEPAGES_DIR"
record_result "大頁測試結(jié)果目錄: $HUGEPAGES_DIR"
record_result "----------------------------------------"
record_result ""
# 分析各項(xiàng)測試結(jié)果
analyze_test_results "full_table_scan"
analyze_test_results "index_scan"
analyze_test_results "dml_operations"
# 生成圖表數(shù)據(jù)
if [ -f "$RESULT_FILE" ]; then
# 提取性能提升數(shù)據(jù)
grep "性能提升" "$RESULT_FILE" > "$ANALYSIS_DIR/improvement_data.txt"
# 創(chuàng)建簡單的性能對比圖表
cat > "$ANALYSIS_DIR/performance_comparison_chart.csv" <<EOF
測試類型,非大頁平均時(shí)間(秒),大頁平均時(shí)間(秒),性能提升(%)
全表掃描,$(grep "全表掃描" "$RESULT_FILE" | awk '{print $5}'),$(grep "全表掃描" "$RESULT_FILE" | awk '{print $12}'),$(grep "全表掃描" "$RESULT_FILE" | awk '{print $15}')
索引掃描,$(grep "索引掃描" "$RESULT_FILE" | awk '{print $5}'),$(grep "索引掃描" "$RESULT_FILE" | awk '{print $12}'),$(grep "索引掃描" "$RESULT_FILE" | awk '{print $15}')
DML操作,$(grep "DML操作" "$RESULT_FILE" | awk '{print $5}'),$(grep "DML操作" "$RESULT_FILE" | awk '{print $12}'),$(grep "DML操作" "$RESULT_FILE" | awk '{print $15}')
EOF
record_result "分析完成,結(jié)果保存在: $RESULT_FILE"
record_result "圖表數(shù)據(jù)保存在: $ANALYSIS_DIR/performance_comparison_chart.csv"
fi (二)腳本run-performance-tests.sh
#!/bin/bash
# Oracle大頁內(nèi)存性能測試 - 測試執(zhí)行腳本
# 檢查是否為oracle用戶
if [ "$(id -un)" != "oracle" ]; then
echo "請使用oracle用戶執(zhí)行此腳本"
exit 1
fi
# 定義常量
ORACLE_SID="TESTDB"
ORACLE_HOME="/u01/app/oracle/product/19.3.0/dbhome_1"
TEST_USER="testuser"
TEST_PASS="testuser"
TEST_RUNS=5
TEST_RESULTS_DIR="$HOME/hugepages_test_results"
LOG_FILE="$TEST_RESULTS_DIR/performance_test_$(date +%Y%m%d_%H%M%S).log"
# 創(chuàng)建結(jié)果目錄
mkdir -p $TEST_RESULTS_DIR
# 記錄日志函數(shù)
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}
# 函數(shù):執(zhí)行SQL測試
run_sql_test() {
local test_name=$1
local sql_statement=$2
local test_file="$TEST_RESULTS_DIR/${test_name}_$(date +%Y%m%d_%H%M%S).txt"
log "開始測試: $test_name"
for ((i=1; i<=$TEST_RUNS; i++)); do
log " 測試運(yùn)行 #$i"
# 執(zhí)行SQL并記錄時(shí)間
{ time $ORACLE_HOME/bin/sqlplus -S $TEST_USER/$TEST_PASS <<EOF
SET TIMING ON
SET SERVEROUTPUT ON
$sql_statement
EXIT;
EOF
; } 2>> $test_file
# 睡眠2秒
sleep 2
done
log "完成測試: $test_name"
}
# 函數(shù):執(zhí)行基準(zhǔn)測試
run_benchmark_tests() {
log "開始執(zhí)行基準(zhǔn)測試..."
# 測試1: 全表掃描
run_sql_test "full_table_scan" "SELECT COUNT(*) FROM test_table;"
# 測試2: 索引掃描
run_sql_test "index_scan" "SELECT * FROM test_table WHERE created_date > SYSDATE - 100;"
# 測試3: DML操作
run_sql_test "dml_operations" "
DECLARE
v_cnt NUMBER;
BEGIN
-- 更新操作
UPDATE test_table SET data = data || '_UPDATED' WHERE MOD(id, 10) = 0;
COMMIT;
-- 刪除操作
DELETE FROM test_table WHERE id > 990000;
COMMIT;
-- 插入操作
FOR i IN 990001..1000000 LOOP
INSERT INTO test_table VALUES (i, 'NEW TEST DATA ' || TO_CHAR(i), SYSDATE);
END LOOP;
COMMIT;
-- 回滾測試
SAVEPOINT sp1;
UPDATE test_table SET data = data || '_TEMP' WHERE MOD(id, 5) = 0;
ROLLBACK TO sp1;
-- 統(tǒng)計(jì)行數(shù)
SELECT COUNT(*) INTO v_cnt FROM test_table;
DBMS_OUTPUT.PUT_LINE('總行數(shù): ' || v_cnt);
END;
/
"
log "基準(zhǔn)測試完成"
}
# 函數(shù):收集AWR報(bào)告
collect_awr_report() {
log "收集AWR報(bào)告..."
local snapshot_id_start=$($ORACLE_HOME/bin/sqlplus -S / as sysdba <<EOF
SET HEADING OFF
SET FEEDBACK OFF
SET PAGESIZE 0
SELECT MAX(snap_id) FROM dba_hist_snapshot;
EXIT;
EOF
)
# 等待10分鐘收集性能數(shù)據(jù)
log "等待10分鐘收集性能數(shù)據(jù)..."
sleep 600
local snapshot_id_end=$($ORACLE_HOME/bin/sqlplus -S / as sysdba <<EOF
SET HEADING OFF
SET FEEDBACK OFF
SET PAGESIZE 0
SELECT MAX(snap_id) FROM dba_hist_snapshot;
EXIT;
EOF
)
local awr_file="$TEST_RESULTS_DIR/awr_report_$(date +%Y%m%d_%H%M%S).html"
# 創(chuàng)建AWR報(bào)告
$ORACLE_HOME/bin/sqlplus -S / as sysdba <<EOF
SET SERVEROUTPUT ON
SPOOL $awr_file
@?/rdbms/admin/awrrpt.sql html
$snapshot_id_start
$snapshot_id_end
7
SPOOL OFF
EXIT;
EOF
log "AWR報(bào)告已生成: $awr_file"
}
# 主函數(shù)
case "$1" in
run-tests)
log "=== 開始性能測試 ==="
run_benchmark_tests
log "=== 性能測試完成 ==="
;;
collect-awr)
log "=== 開始收集AWR報(bào)告 ==="
collect_awr_report
log "=== AWR報(bào)告收集完成 ==="
;;
*)
echo "用法: $0 [run-tests|collect-awr]"
echo " run-tests - 執(zhí)行基準(zhǔn)測試"
echo " collect-awr - 收集AWR性能報(bào)告"
exit 1
;;
esac (三)腳本setup-test-env.sh
#!/bin/bash
# Oracle大頁內(nèi)存性能測試 - 環(huán)境準(zhǔn)備腳本
# 檢查是否為root用戶
if [ "$(id -u)" -ne 0 ]; then
echo "請使用root用戶執(zhí)行此腳本"
exit 1
fi
# 定義常量
SGA_SIZE_GB=8
HUGEPAGE_SIZE_MB=2
HUGEPAGE_COUNT=$((SGA_SIZE_GB * 1024 / HUGEPAGE_SIZE_MB))
ORACLE_SID="TESTDB"
ORACLE_HOME="/u01/app/oracle/product/19.3.0/dbhome_1"
# 函數(shù):配置大頁內(nèi)存
configure_hugepages() {
echo "配置大頁內(nèi)存..."
# 修改sysctl.conf
cat >> /etc/sysctl.conf <<EOF
# 配置大頁內(nèi)存用于Oracle性能測試
vm.nr_hugepages = $HUGEPAGE_COUNT
vm.transparent_hugepage.enabled = never
vm.transparent_hugepage.khugepaged = never
EOF
# 使配置生效
sysctl -p
# 配置大頁掛載點(diǎn)
if ! grep -q "hugetlbfs" /etc/fstab; then
echo "none /dev/hugepages hugetlbfs defaults 0 0" >> /etc/fstab
mkdir -p /dev/hugepages
mount -a
fi
echo "大頁內(nèi)存配置完成"
}
# 函數(shù):禁用大頁內(nèi)存
disable_hugepages() {
echo "禁用大頁內(nèi)存..."
# 修改sysctl.conf
sed -i '/vm.nr_hugepages/d' /etc/sysctl.conf
sed -i '/vm.transparent_hugepage/d' /etc/sysctl.conf
# 添加禁用配置
cat >> /etc/sysctl.conf <<EOF
# 禁用大頁內(nèi)存
vm.nr_hugepages = 0
vm.transparent_hugepage.enabled = always
vm.transparent_hugepage.khugepaged = always
EOF
# 使配置生效
sysctl -p
# 卸載大頁掛載點(diǎn)
if grep -q "hugetlbfs" /etc/fstab; then
umount /dev/hugepages 2>/dev/null
sed -i '/hugetlbfs/d' /etc/fstab
fi
echo "大頁內(nèi)存已禁用"
}
# 函數(shù):配置Oracle使用大頁
configure_oracle_hugepages() {
echo "配置Oracle使用大頁內(nèi)存..."
su - oracle -c "$ORACLE_HOME/bin/sqlplus / as sysdba <<EOF
ALTER SYSTEM SET sga_target=${SGA_SIZE_GB}G SCOPE=SPFILE;
ALTER SYSTEM SET use_large_pages=TRUE SCOPE=SPFILE;
EXIT;
EOF"
echo "Oracle大頁配置完成,請重啟數(shù)據(jù)庫使配置生效"
}
# 函數(shù):配置Oracle不使用大頁
configure_oracle_no_hugepages() {
echo "配置Oracle不使用大頁內(nèi)存..."
su - oracle -c "$ORACLE_HOME/bin/sqlplus / as sysdba <<EOF
ALTER SYSTEM SET sga_target=${SGA_SIZE_GB}G SCOPE=SPFILE;
ALTER SYSTEM SET use_large_pages=FALSE SCOPE=SPFILE;
EXIT;
EOF"
echo "Oracle大頁配置已禁用,請重啟數(shù)據(jù)庫使配置生效"
}
# 函數(shù):創(chuàng)建測試用戶和表
create_test_objects() {
echo "創(chuàng)建測試用戶和表..."
su - oracle -c "$ORACLE_HOME/bin/sqlplus / as sysdba <<EOF
CREATE USER testuser IDENTIFIED BY testuser DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp;
GRANT CONNECT, RESOURCE, DBA TO testuser;
EXIT;
EOF"
# 創(chuàng)建測試表
su - oracle -c "$ORACLE_HOME/bin/sqlplus testuser/testuser <<EOF
CREATE TABLE test_table (
id NUMBER PRIMARY KEY,
data VARCHAR2(4000),
created_date DATE
);
-- 插入100萬條測試數(shù)據(jù)
BEGIN
FOR i IN 1..1000000 LOOP
INSERT INTO test_table VALUES (i, 'TEST DATA ' || TO_CHAR(i), SYSDATE);
IF MOD(i, 10000) = 0 THEN
COMMIT;
END IF;
END LOOP;
COMMIT;
END;
/
-- 創(chuàng)建索引
CREATE INDEX idx_test_table ON test_table(created_date);
EXIT;
EOF"
echo "測試對象創(chuàng)建完成"
}
# 主函數(shù)
case "$1" in
enable-hugepages)
configure_hugepages
configure_oracle_hugepages
;;
disable-hugepages)
disable_hugepages
configure_oracle_no_hugepages
;;
create-test-data)
create_test_objects
;;
*)
echo "用法: $0 [enable-hugepages|disable-hugepages|create-test-data]"
echo " enable-hugepages - 配置并啟用大頁內(nèi)存"
echo " disable-hugepages - 禁用大頁內(nèi)存"
echo " create-test-data - 創(chuàng)建測試數(shù)據(jù)"
exit 1
;;
esac (四)使用說明test-procedure.md
# Oracle大頁內(nèi)存性能測試實(shí)驗(yàn)步驟 ## 一、測試環(huán)境準(zhǔn)備 ### 1. 系統(tǒng)和數(shù)據(jù)庫配置 確保測試環(huán)境滿足以下條件: - Linux操作系統(tǒng)(推薦Oracle Linux 7或Red Hat Enterprise Linux 7及以上版本) - Oracle數(shù)據(jù)庫(12c及以上版本) - 足夠的內(nèi)存(建議至少16GB) - 測試數(shù)據(jù)庫實(shí)例 ### 2. 安裝測試腳本 將提供的三個(gè)腳本文件復(fù)制到測試服務(wù)器: - setup-test-env.sh - 環(huán)境準(zhǔn)備腳本 - run-performance-tests.sh - 測試執(zhí)行腳本 - analyze-results.sh - 結(jié)果分析腳本 確保腳本具有執(zhí)行權(quán)限:chmod +x setup-test-env.sh run-performance-tests.sh analyze-results.sh ## 二、執(zhí)行測試 ### 1. 禁用大頁內(nèi)存并進(jìn)行測試 首先,以root用戶執(zhí)行以下命令禁用大頁內(nèi)存并配置Oracle不使用大頁:./setup-test-env.sh disable-hugepages 重啟系統(tǒng)使配置生效:shutdown -r now 系統(tǒng)重啟后,以oracle用戶連接數(shù)據(jù)庫并啟動(dòng)數(shù)據(jù)庫:sqlplus / as sysdba STARTUP 創(chuàng)建測試數(shù)據(jù):./setup-test-env.sh create-test-data 執(zhí)行基準(zhǔn)測試并收集結(jié)果:mkdir -p ~/non_hugepages_results ./run-performance-tests.sh run-tests > ~/non_hugepages_results/test_log_$(date +%Y%m%d).txt ./run-performance-tests.sh collect-awr > ~/non_hugepages_results/awr_log_$(date +%Y%m%d).txt ### 2. 啟用大頁內(nèi)存并進(jìn)行測試 以root用戶執(zhí)行以下命令啟用大頁內(nèi)存并配置Oracle使用大頁:./setup-test-env.sh enable-hugepages 重啟系統(tǒng)使配置生效:shutdown -r now 系統(tǒng)重啟后,以oracle用戶連接數(shù)據(jù)庫并啟動(dòng)數(shù)據(jù)庫:sqlplus / as sysdba STARTUP 執(zhí)行基準(zhǔn)測試并收集結(jié)果:mkdir -p ~/hugepages_results ./run-performance-tests.sh run-tests > ~/hugepages_results/test_log_$(date +%Y%m%d).txt ./run-performance-tests.sh collect-awr > ~/hugepages_results/awr_log_$(date +%Y%m%d).txt ## 三、分析測試結(jié)果 以oracle用戶執(zhí)行結(jié)果分析腳本:./analyze-results.sh ~/non_hugepages_results ~/hugepages_results 分析腳本會(huì)生成詳細(xì)的測試對比結(jié)果和圖表數(shù)據(jù),查看結(jié)果文件:cat ~/hugepages_analysis_*/comparison_results.txt ## 四、實(shí)驗(yàn)結(jié)果解讀 分析結(jié)果文件中的數(shù)據(jù),重點(diǎn)關(guān)注以下指標(biāo): 1. 各項(xiàng)測試(全表掃描、索引掃描、DML操作)在啟用大頁和未啟用大頁情況下的執(zhí)行時(shí)間對比 2. 性能提升百分比 3. AWR報(bào)告中的內(nèi)存使用情況、CPU使用率等關(guān)鍵指標(biāo) 通常情況下,啟用大頁內(nèi)存后,Oracle數(shù)據(jù)庫的性能會(huì)有明顯提升,尤其是在內(nèi)存訪問密集型操作中。 ## 五、注意事項(xiàng) 1. 在測試過程中,確保系統(tǒng)負(fù)載穩(wěn)定,避免其他應(yīng)用程序干擾測試結(jié)果 2. 測試前關(guān)閉所有不必要的服務(wù)和進(jìn)程 3. 建議進(jìn)行多次測試以確保結(jié)果的可靠性 4. 測試完成后,可以根據(jù)實(shí)際情況決定是否在生產(chǎn)環(huán)境中啟用大頁內(nèi)存配置
這個(gè)實(shí)驗(yàn)設(shè)計(jì)通過對比啟用和禁用大頁內(nèi)存兩種情況下 Oracle 數(shù)據(jù)庫的性能表現(xiàn),能夠直觀地展示大頁內(nèi)存對數(shù)據(jù)庫性能的影響。實(shí)驗(yàn)包含完整的環(huán)境準(zhǔn)備、測試執(zhí)行和結(jié)果分析流程,通過多種測試場景(全表掃描、索引掃描、DML 操作)驗(yàn)證大頁內(nèi)存的性能優(yōu)勢。
在執(zhí)行實(shí)驗(yàn)時(shí),請按照測試步驟說明依次操作,并根據(jù)實(shí)際環(huán)境調(diào)整相關(guān)參數(shù)(如 SGA 大小、測試數(shù)據(jù)量等)。測試完成后,通過分析結(jié)果文件中的性能數(shù)據(jù)和圖表,你將能夠清晰地看到啟用大頁內(nèi)存后 Oracle 數(shù)據(jù)庫的性能提升情況。
六、總結(jié)
通過以上步驟,我們完成了 Oracle 在 Linux 上的大頁配置。合理配置大頁內(nèi)存能夠有效提升 Oracle 數(shù)據(jù)庫的性能和穩(wěn)定性,但在配置過程中需要注意參數(shù)的準(zhǔn)確設(shè)置,并根據(jù)實(shí)際環(huán)境進(jìn)行適當(dāng)調(diào)整。在實(shí)際應(yīng)用中,還可以結(jié)合其他性能優(yōu)化手段,進(jìn)一步提升數(shù)據(jù)庫的整體表現(xiàn)。?
以上就是Linux環(huán)境下Oracle大頁配置全過程的詳細(xì)內(nèi)容,更多關(guān)于Linux Oracle大頁配置的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Oracle數(shù)據(jù)庫表名支持的最大長度是多少
這篇文章主要介紹了Oracle數(shù)據(jù)庫表名支持的最大長度,本文通過Oracle標(biāo)識(shí)符確認(rèn)了表名的最大支持字符串為30個(gè)字符,需要的朋友可以參考下2014-08-08
Oracle?Database?23c新特性之關(guān)聯(lián)更新和刪除示例詳解
這篇文章主要介紹了Oracle?Database?23c新特性之關(guān)聯(lián)更新和刪除的相關(guān)資料,Oracle database 23c開始支持在UPDATE和DELETE語句中使用JOIN連接,獲取更新和刪除的數(shù)據(jù)源,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06
通過LogMiner實(shí)現(xiàn)Oracle數(shù)據(jù)庫同步遷移
為了實(shí)現(xiàn)Oracle數(shù)據(jù)庫之間的數(shù)據(jù)同步,網(wǎng)上的資料比較少的時(shí)候。最好用的Oracle數(shù)據(jù)庫同步工具是:GoldenGate ,而GoldenGate是要收費(fèi)的。這個(gè)時(shí)候就可以使用LogMiner來實(shí)現(xiàn)Oracle數(shù)據(jù)同步遷移,下面文章內(nèi)容將給大家介紹其實(shí)現(xiàn)方法2021-09-09
Oracle數(shù)據(jù)庫新建用戶及分配表空間方式
本文詳細(xì)介紹了如何在數(shù)據(jù)庫中新建表空間、創(chuàng)建用戶及授予權(quán)限,并提供了查看表空間信息的方法,助力數(shù)據(jù)庫管理優(yōu)化2026-06-06
Oracle數(shù)據(jù)庫恢復(fù)教程之resetlogs操作
這篇文章主要給大家介紹了關(guān)于Oracle數(shù)據(jù)庫恢復(fù)教程之resetlogs操作的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Oracle數(shù)據(jù)庫具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05

