1. 程式人生 > >Zabbix歷史資料庫遷移 及分割槽

Zabbix歷史資料庫遷移 及分割槽

公司zabbix用了很久了,大概有80G的歷史資料。機器記憶體也不是多大,所以決定遷移zabbix後臺資料庫,並在新機器上開啟分割槽。
zabbix資料庫裡 主要的大表為以下幾個, 系統同事又提出需要儲存trends兩個表的資料:

history,history_text,history_log,history_str,history_unit (遷移時不需要保留)
trends, trend_unit (遷移時需要保留資料)

操作步驟:

1 . 在新機器上搭好mysql。
2 . 在老機器上上 dump出一份只有表定義的檔案,傳到新庫:

mysqldump -uroot -p
zabbix -d > zabbix_d.sql

3 . 在老機器上上 dump出表內容檔案,這個檔案要排除掉一些不需要遷移的歷史資料表:

mysqldump -uroot -p zabbix -t --ignore-table=zabbix.history_log --ignore-table=zabbix.history --ignore-table=zabbix.history_text --ignore-table=zabbix.history_uint --ignore-table=zabbix.history_str >zabbix_t.sql

這步驟可能需要一定時間,因為trends的那兩個表也不小,我們同時在新庫上繼續操作。

後續確認 trends的兩個表也可以不要清楚資料。

4 .新機器上修改兩個表的結構新增索引:

use zabbix
truncate table history;
optimize  table history;
truncate table history_uint;
truncate table history_str;

alter table history_text drop primary key, add index (id), drop index history_text_2, add index history_text_2 (itemid, id);
alter
table history_log drop primary key, add index (id), drop index history_log_2, add index history_log_2 (itemid, id);

5 .新增自動分割槽的儲存過程:

DELIMITER $$
CREATE PROCEDURE `partition_create`(SCHEMANAME varchar(64), TABLENAME varchar(64), PARTITIONNAME varchar(64), CLOCK int)
BEGIN
        /*
           SCHEMANAME = The DB schema in which to make changes
           TABLENAME = The table with partitions to potentially delete
           PARTITIONNAME = The name of the partition to create
        */
        /*
           Verify that the partition does not already exist
        */

        DECLARE RETROWS INT;
        SELECT COUNT(1) INTO RETROWS
        FROM information_schema.partitions
        WHERE table_schema = SCHEMANAME AND table_name = TABLENAME AND partition_description >= CLOCK;

        IF RETROWS = 0 THEN
                /*
                   1. Print a message indicating that a partition was created.
                   2. Create the SQL to create the partition.
                   3. Execute the SQL from #2.
                */
                SELECT CONCAT( "partition_create(", SCHEMANAME, ",", TABLENAME, ",", PARTITIONNAME, ",", CLOCK, ")" ) AS msg;
                SET @sql = CONCAT( 'ALTER TABLE ', SCHEMANAME, '.', TABLENAME, ' ADD PARTITION (PARTITION ', PARTITIONNAME, ' VALUES LESS THAN (', CLOCK, '));' );
                PREPARE STMT FROM @sql;
                EXECUTE STMT;
                DEALLOCATE PREPARE STMT;
        END IF;
END$$
DELIMITER ;

DELIMITER $$
CREATE PROCEDURE `partition_drop`(SCHEMANAME VARCHAR(64), TABLENAME VARCHAR(64), DELETE_BELOW_PARTITION_DATE BIGINT)
BEGIN
        /*
           SCHEMANAME = The DB schema in which to make changes
           TABLENAME = The table with partitions to potentially delete
           DELETE_BELOW_PARTITION_DATE = Delete any partitions with names that are dates older than this one (yyyy-mm-dd)
        */
        DECLARE done INT DEFAULT FALSE;
        DECLARE drop_part_name VARCHAR(16);

        /*
           Get a list of all the partitions that are older than the date
           in DELETE_BELOW_PARTITION_DATE.  All partitions are prefixed with
           a "p", so use SUBSTRING TO get rid of that character.
        */
        DECLARE myCursor CURSOR FOR
                SELECT partition_name
                FROM information_schema.partitions
                WHERE table_schema = SCHEMANAME AND table_name = TABLENAME AND CAST(SUBSTRING(partition_name FROM 2) AS UNSIGNED) < DELETE_BELOW_PARTITION_DATE;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

        /*
           Create the basics for when we need to drop the partition.  Also, create
           @drop_partitions to hold a comma-delimited list of all partitions that
           should be deleted.
        */
        SET @alter_header = CONCAT("ALTER TABLE ", SCHEMANAME, ".", TABLENAME, " DROP PARTITION ");
        SET @drop_partitions = "";

        /*
           Start looping through all the partitions that are too old.
        */
        OPEN myCursor;
        read_loop: LOOP
                FETCH myCursor INTO drop_part_name;
                IF done THEN
                        LEAVE read_loop;
                END IF;
                SET @drop_partitions = IF(@drop_partitions = "", drop_part_name, CONCAT(@drop_partitions, ",", drop_part_name));
        END LOOP;
        IF @drop_partitions != "" THEN
                /*
                   1. Build the SQL to drop all the necessary partitions.
                   2. Run the SQL to drop the partitions.
                   3. Print out the table partitions that were deleted.
                */
                SET @full_sql = CONCAT(@alter_header, @drop_partitions, ";");
                PREPARE STMT FROM @full_sql;
                EXECUTE STMT;
                DEALLOCATE PREPARE STMT;

                SELECT CONCAT(SCHEMANAME, ".", TABLENAME) AS `table`, @drop_partitions AS `partitions_deleted`;
        ELSE
                /*
                   No partitions are being deleted, so print out "N/A" (Not applicable) to indicate
                   that no changes were made.
                */
                SELECT CONCAT(SCHEMANAME, ".", TABLENAME) AS `table`, "N/A" AS `partitions_deleted`;
        END IF;
END$$
DELIMITER ;

DELIMITER $$
CREATE PROCEDURE `partition_maintenance`(SCHEMA_NAME VARCHAR(32), TABLE_NAME VARCHAR(32), KEEP_DATA_DAYS INT, HOURLY_INTERVAL INT, CREATE_NEXT_INTERVALS INT)
BEGIN
        DECLARE OLDER_THAN_PARTITION_DATE VARCHAR(16);
        DECLARE PARTITION_NAME VARCHAR(16);
        DECLARE OLD_PARTITION_NAME VARCHAR(16);
        DECLARE LESS_THAN_TIMESTAMP INT;
        DECLARE CUR_TIME INT;

        CALL partition_verify(SCHEMA_NAME, TABLE_NAME, HOURLY_INTERVAL);
        SET CUR_TIME = UNIX_TIMESTAMP(DATE_FORMAT(NOW(), '%Y-%m-%d 00:00:00'));

        SET @__interval = 1;
        create_loop: LOOP
                IF @__interval > CREATE_NEXT_INTERVALS THEN
                        LEAVE create_loop;
                END IF;

                SET LESS_THAN_TIMESTAMP = CUR_TIME + (HOURLY_INTERVAL * @__interval * 3600);
                SET PARTITION_NAME = FROM_UNIXTIME(CUR_TIME + HOURLY_INTERVAL * (@__interval - 1) * 3600, 'p%Y%m%d%H00');
                IF(PARTITION_NAME != OLD_PARTITION_NAME) THEN
      CALL partition_create(SCHEMA_NAME, TABLE_NAME, PARTITION_NAME, LESS_THAN_TIMESTAMP);
    END IF;
                SET @[email protected]__interval+1;
                SET OLD_PARTITION_NAME = PARTITION_NAME;
        END LOOP;

        SET OLDER_THAN_PARTITION_DATE=DATE_FORMAT(DATE_SUB(NOW(), INTERVAL KEEP_DATA_DAYS DAY), '%Y%m%d0000');
        CALL partition_drop(SCHEMA_NAME, TABLE_NAME, OLDER_THAN_PARTITION_DATE);

END$$
DELIMITER ;

DELIMITER $$
CREATE PROCEDURE `partition_verify`(SCHEMANAME VARCHAR(64), TABLENAME VARCHAR(64), HOURLYINTERVAL INT(11))
BEGIN
        DECLARE PARTITION_NAME VARCHAR(16);
        DECLARE RETROWS INT(11);
        DECLARE FUTURE_TIMESTAMP TIMESTAMP;

        /*
         * Check if any partitions exist for the given SCHEMANAME.TABLENAME.
         */
        SELECT COUNT(1) INTO RETROWS
        FROM information_schema.partitions
        WHERE table_schema = SCHEMANAME AND table_name = TABLENAME AND partition_name IS NULL;

        /*
         * If partitions do not exist, go ahead and partition the table
         */
        IF RETROWS = 1 THEN
                /*
                 * Take the current date at 00:00:00 and add HOURLYINTERVAL to it.  This is the timestamp below which we will store values.
                 * We begin partitioning based on the beginning of a day.  This is because we don't want to generate a random partition
                 * that won't necessarily fall in line with the desired partition naming (ie: if the hour interval is 24 hours, we could
                 * end up creating a partition now named "p201403270600" when all other partitions will be like "p201403280000").
                 */
                SET FUTURE_TIMESTAMP = TIMESTAMPADD(HOUR, HOURLYINTERVAL, CONCAT(CURDATE(), " ", '00:00:00'));
                SET PARTITION_NAME = DATE_FORMAT(CURDATE(), 'p%Y%m%d%H00');

                -- Create the partitioning query
                SET @__PARTITION_SQL = CONCAT("ALTER TABLE ", SCHEMANAME, ".", TABLENAME, " PARTITION BY RANGE(`clock`)");
                SET @__PARTITION_SQL = CONCAT(@__PARTITION_SQL, "(PARTITION ", PARTITION_NAME, " VALUES LESS THAN (", UNIX_TIMESTAMP(FUTURE_TIMESTAMP), "));");

                -- Run the partitioning query
                PREPARE STMT FROM @__PARTITION_SQL;
                EXECUTE STMT;
                DEALLOCATE PREPARE STMT;
        END IF;
END$$
DELIMITER ;

6 . 把儲存過程匯入資料庫:

use zabbix
source zabbix_par.sql;

7 . 建立一個批量呼叫產生分割槽的儲存過程

cat zabbix_cal.sql

DELIMITER $$
CREATE PROCEDURE `partition_maintenance_all`(SCHEMA_NAME VARCHAR(32))
BEGIN
                CALL partition_maintenance(SCHEMA_NAME, 'history', 28, 24, 14);
                CALL partition_maintenance(SCHEMA_NAME, 'history_log', 28, 24, 14);
                CALL partition_maintenance(SCHEMA_NAME, 'history_str', 28, 24, 14);
                CALL partition_maintenance(SCHEMA_NAME, 'history_text', 28, 24, 14);
                CALL partition_maintenance(SCHEMA_NAME, 'history_uint', 28, 24, 14);
                CALL partition_maintenance(SCHEMA_NAME, 'trends', 730, 24, 14);
                CALL partition_maintenance(SCHEMA_NAME, 'trends_uint', 730, 24, 14);
END$$
DELIMITER ;

8 . 把這個儲存過程載入zabbix庫

mysql -uzabbix -pzabbix zabbix  <  zabbix_cal.sql

CALL partition_maintenance(SCHEMA_NAME, ‘history_text’, 28, 24, 14);
保留28天資料, 每24小時建立一次分割槽,每次建立14個分割槽。
修改的時候儘量改28. 和 14 ,中間的24不要修改。

9 . 以後每天定期排程這個儲存過程:

crontab -l

00 01 * * * /usr/local/bin/mysql -uzabbix -pzabbix zabbix -e "CALL partition_maintenance_all('zabbix');"

相關推薦

Zabbix歷史資料庫遷移 分割槽

公司zabbix用了很久了,大概有80G的歷史資料。機器記憶體也不是多大,所以決定遷移zabbix後臺資料庫,並在新機器上開啟分割槽。 zabbix資料庫裡 主要的大表為以下幾個, 系統同事又提出需要儲存trends兩個表的資料: history,hi

Flask資料庫遷移建表

1 資料庫遷移 1.1 目錄結構 |-- app | |-- __init__.py | |-- __pycache__ |-- config.py | |-- README | |-- __pycache__ | |-- alembic.ini | |-

Flask修煉——資料庫遷移藍圖!

內容概述: 資料庫遷移、 藍圖、 單元測試。 資料庫遷移 在開發過程中,需要修改資料庫模型,而且還要在修改之後更新資料庫。最直接的方式就是刪除舊錶,但這樣會丟失資料。 更好的解決辦法是使用資料庫遷移框架,它可以追蹤資料庫模式的

lavarel-資料庫遷移artisan常用命令

檢視解析 lavarel前端檔案儲存為.blade.php型別的檔案,解析方法為{{}} 也可以用.php結尾,但是解析時只能用原生方法<?php echo $title;?> 資料庫遷移 資料庫配置檔案在/.env檔案中 遷移檔案用命令生成,不需要自己寫,生成後再補

zabbix 歷史數據清理libdata1文件過大處理

博客 查看 res oca localhost eight temp 51cto mysql 一 歷史數據清理 停止相關服務,避免寫入數據/etc/init.d/zabbix-server stop /etc/init.d/httpd stop 清空歷史數據m

量化策略多因子選股之抓取不同時段的歷史價格,資料庫操作

#獲取20170831,20180323的滬深三百成分及中證500的成分股當日收盤價 # coding=utf-8 import pandas as pd import tushare as ts import sys from sqlalchemy import create_engi

zabbix遷移資料庫遷移 5.1-5.6

2016-07-04 23:29:20 24086 [ERROR] Native table 'performance_schema'.'table_io_waits_summary_by_index_usage' has the wrong structure 2016-07-04 23:29:20 24

Oracle用分割槽分割槽交換做歷史資料遷移

一。說明:      OLTP庫中有些表資料量大,且每月有持續的大量資料增加,由於歷史資料在此庫中不再做訪問,而是在另1個OLAP庫中做分析,所以會對歷史資料遷移至OLAP庫中。對這種歷史資料遷移的操作,較好的辦法是該表採用分割槽表。按時間分割槽後,可以對分割槽進行遷移。

postgresql資料庫跨機冷遷移問題處理

環境: 資料庫版本:postgresql 9.5 作業系統A:linux   4 作業系統B:linux        5.8 操作內容: 將部署在伺服器A(*.*.201.210)上的PG9.5軟體及資料庫資料,遷移到伺服器B(*.*.188.197)的相同目錄。

資料庫遷移至SQLiteSQLite常用命令

Oracle遷移至SQLite 1. 從PL/SQL 中查詢你要的資料,然後匯出成CSV格式檔案; 也可以使用指令碼進行匯出CSV檔案,具體如下: --set colsep ' || '; set echo off; set feedback off; --禁止顯示最後一行的計數反

MySQL資料庫遷移到SQL Server----------SSMA(SQL Server Migration Assistant for MySQL)工具安裝使用

1.檢視SQLServer的版本: 開啟Microsoft SQL Server Management Studio,點選New Query,輸入“SELECT @@VERSION”,返回當前安裝的日期、版本和處理器型別。 2.檢視MySql版本 開始->

oracle資料庫遷移至mysql 之 sysdate格式化運算替換

例1,查詢當前系統日期 select to_char(sysdate,'yyyy-mm-dd') from dual 替換為 select current_date; 或者 select curdate(); 例2,查詢當前系統時間 select to_c

[Oracle資料庫] oracle資料庫字符集characterset遷移變更之csscancsalter.plb系列三

背景 本文主要熟悉下如何用csscan以及csalter指令碼變更資料庫字符集,進一步理解如何調整資料庫字符集的知識。 之前的相關文章連結: oracle10g_csscan_更變資料庫字符集及國家字符集的工具測試 http://blog.itpub.net/9240380/viewspace-614070/

海量資料庫分割槽3——《12年資深DBA教你Oracle開發與優化——效能優化部分》

1.全分割槽智慧連線    此時,將來自於相連的兩個表的一對分割槽之間的很大的連線分解成小連線。只有當基於連線鍵的兩個表是均衡的,或者參照分割槽時才可使用本特徵。如: 假定表sales和customers通過列customer_id相連,該連線是一個大連線,查詢某個1999年第三季度購買次數超過100的客戶

海量資料庫分割槽3——《12年資深DBA教你Oracle開發與優化——效能優化部分》...

1.全分割槽智慧連線    此時,將來自於相連的兩個表的一對分割槽之間的很大的連線分解成小連線。只有當基於連線鍵的兩個表是均衡的,或者參照分割槽時才可使用本特徵。如: 假定表sales和customers通過列customer_id相連,該連線是一個大連線,查詢某個1999年第三季度購買次數超過100的客戶

Linux下informix安裝資料庫遷移

今天碰到informix環境,使用onstat、oninit報錯,發現由於是新部署的環境,很多配置沒有更改,現仍未解決。 =====以下內容來源網上,但通過自己實踐,並重新整理過了== 1.建立informix使用者和組。 useradd informix 2. informix使用者登入,並設定一些環境變數

MySql 使用 EF Core 2.0 CodeFirst、DbFirst、資料庫遷移(Migration)介紹示例

dotnet core 2.0 釋出已經好幾天了,期間也把原來 dotnet core 1.1 的 MVC 專案升級到了 2.0,升級過程還是比較順利的,變動也不是太多。升級的過程中也少不了 Entity Framwork Core 的升級,在這篇文章中主要介紹下 MySql

關係型資料庫大資料效能優化解決方案之:分表(當前表歷史表)、表分割槽、資料清理原則

原因和目的由於交易量大或者日積月累造成資料庫的資料量越來越大。會導致系統性能大幅下降,所以要對部分業務的表資料作備份和清理減少資料量,來提升請求響應的速度,提升使用者體驗資料是否需要清理的閥值判斷通常當表的磁碟大小超過 5GB,或對於 OLTP 系統(聯機事務處理),表的記錄

10、管理數據庫存儲(行遷移行連接)

管理數據庫存儲(行遷移及行連接)管理數據庫存儲1block=8192bytes案例1:行遷移1、表中數據如何存儲create table test as select * from hr.employees;create index idx_test on test(employee_id);只看執行計劃,不

清理zabbix歷史數據

zabbix清理腳本#!/bin/bash Date=`date -d $(date -d "-30 day" +%Y%m%d) +%s` /usr/local/mysql/bin/mysql --login-path=zabbix -e" use zabbix; DELETE FROM history WH