1

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

  1. 将 auto_increment 保存在 radacct
  2. 半径工作时进行切割
  3. 将所有行保留为活动会话
  4. 将所有已关闭会话的行移动到存档数据库中的 radacct

我开始为此做一个程序

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 服务器来执行此步骤。我怎样才能顺利地为半径做到这一点?也许我在这个优化中走错了路?

更新这个脚本可以满足我的需要

/*
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 的负载是否更重。

4

1 回答 1

0

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

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

于 2014-03-16T09:07:52.500 回答