切割/优化radacct表(FreeRADIUS)

时间:2014-03-14 08:25:48

标签: mysql sql freeradius

我尝试优化radacct表,该表增长到91628239行并且正在增长。我决定剪切表格的最旧部分并将其放入存档数据库。我需要:

  1. 在radacct中保存auto_increment
  2. 在半径工作时进行切割
  3. 保留所有具有活动会话的行
  4. 将具有已关闭会话的所有行移至存档db中的radacct
  5. 我开始为此

    制作程序
    BEGIN
    /**
     clean up radacct table procedure
    */
    
    -- create fresh radacct table same as old radacct and same auto_increment value
    CREATE TABLE db5.radacct_fresh LIKE db5.radacct;
    SELECT @my_auto_increment:=auto_increment FROM information_schema.tables WHERE table_name='radacct' AND table_schema='db5';
    SET @query = CONCAT("ALTER TABLE db5.radacct_fresh auto_increment = ", @my_auto_increment);
    PREPARE stmt FROM @query;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    
    -- copy active sessions to fresh table
    INSERT INTO radacct_fresh SELECT * FROM radacct WHERE acctstoptime IS NULL;
    
    -- move radacct to db5h
    SET @query = CONCAT('ALTER TABLE db5.radacct RENAME db5h.radacct_', UNIX_TIMESTAMP());
    PREPARE stmt FROM @query;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    END
    

    我无法停止radius服务器来执行此步骤。如何顺利地完成半径? 也许我在这个优化中走错了路?

    UPDATE 此脚本正在满足我的需求

    /*
    clean up radacct table procedure
    */
    
    -- create fresh radacct table same as old radacct and same auto_increment value
    DROP TABLE IF EXISTS db5.radacct_fresh;
    CREATE TABLE db5.radacct_fresh LIKE db5.radacct;
    
    LOCK TABLES db5.radacct WRITE, db5.radacct_fresh WRITE;
    -- make auto_increment same as in radacct
    SELECT @my_auto_increment:=auto_increment FROM information_schema.tables WHERE table_name='radacct' AND table_schema='db5';
    SET @query = CONCAT("ALTER TABLE db5.radacct_fresh auto_increment = ", @my_auto_increment);
    PREPARE stmt FROM @query;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    
    -- copy active sessions to fresh table
    INSERT INTO db5.radacct_fresh SELECT * FROM radacct WHERE acctstoptime IS NULL;
    
    -- move radacct to db5H
    SET @query = CONCAT('ALTER TABLE db5.radacct RENAME db5H.radacct_', UNIX_TIMESTAMP());
    PREPARE stmt FROM @query;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    
    -- make fresh table as main
    ALTER TABLE db5.radacct_fresh RENAME db5.radacct;
    
    UNLOCK TABLES;
    

    更新

    我已经为半径

    制定了这个方案
    CREATE DEFINER=`root`@`%` PROCEDURE `archive_radacct`(AST int(11), ASEST int(12), AINOCT bigint(20), AOUTOCT bigint(20), ATERMC varchar(32), ASTD int(12), CIS varchar(50), ASESID varchar(32), UN varchar(64), NASIP int(11))
    BEGIN
    UPDATE db5.radacct SET
    acctstoptime = AST,
    acctsessiontime = ASEST,
    acctinputoctets = AINOCT,
    acctoutputoctets =AOUTOCT,
    acctterminatecause =ATERMC,
    acctstopdelay =ASTD,
    connectinfo_stop = CIS
    WHERE acctsessionid = ASESID
    AND username = UN
    AND nasipaddress = NASIP;
    
    DELETE FROM db5.radacct WHERE
    acctsessionid = ASESID
    AND username = UN
    AND nasipaddress = NASIP;
    END
    CREATE TRIGGER archive_radacct_row BEFOR DELETE ON db5.radacct FOR EACH ROW BEGIN
    INSERT INTO db5H.radacct SELECT * FROM db5.radacct WHERE radacctid = OLD.radacctid
    END
    

    接收Acct-stop时的Radius CALL存档radacct。我在我的一个生产半径服务器上测试了这个方案。我试图找出它对DB来说是更重的负载。

1 个答案:

答案 0 :(得分:0)

更好的方法是在更新时触发,将acctstoptime设置为非NULL值,将受影响的行移动到历史表中。

然后FreeRADIUS继续使用活动表中的行集。