代码之家  ›  专栏  ›  技术社区  ›  Oscar Jofre

MariaDB BIGINT UNSIGNED值超出范围

  •  -1
  • Oscar Jofre  · 技术社区  · 8 年前

    我一直在阅读有关此错误的信息,但找不到如何修复此错误。 我在这句话中每小时都有一个时间表:

     UPDATE radacct SET 
                radacct.AcctStopTime=NOW(),
                radacct.AcctTerminateCause='Stale-Session'
            WHERE ((UNIX_TIMESTAMP(NOW()) - (UNIX_TIMESTAMP(radacct.acctstarttime) + radacct.acctsessiontime)) > (60*6+60*6))
                AND (AcctStopTime = '0000-00-00 00:00:00' OR AcctStopTime IS NULL)
    

    有时我会遇到这个错误:

     BIGINT UNSIGNED value is out of range in '(unix_timestamp(now()) - (unix_timestamp(`radius`.`radacct`.`acctstarttime`) + `radius`.`radacct`.`acctsessiontime`))'
    

    这是创建表:

     CREATE TABLE `radacct` (
       `radacctid` bigint(21) NOT NULL AUTO_INCREMENT,
       `acctsessionid` varchar(64) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
       `acctuniqueid` varchar(32) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
       `username` varchar(64) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
       `groupname` varchar(64) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
       `realm` varchar(64) COLLATE utf8_unicode_ci DEFAULT '',
       `nasipaddress` varchar(15) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
       `nasportid` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL,
       `nasporttype` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
       `acctstarttime` datetime DEFAULT NULL,
       `acctupdatetime` datetime DEFAULT NULL,
       `acctstoptime` datetime DEFAULT NULL,
       `acctinterval` int(12) DEFAULT NULL,
       `acctsessiontime` int(12) unsigned DEFAULT NULL,
       `acctauthentic` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
       `connectinfo_start` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
       `connectinfo_stop` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
       `acctinputoctets` bigint(20) DEFAULT NULL,
       `acctoutputoctets` bigint(20) DEFAULT NULL,
       `calledstationid` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
       `callingstationid` varchar(50) COLLATE utf8_unicode_ci NOT NULL      DEFAULT '',
       `acctterminatecause` varchar(32) COLLATE utf8_unicode_ci NOT NULL      DEFAULT '',
       `servicetype` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
       `framedprotocol` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
       `framedipaddress` varchar(15) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
       PRIMARY KEY (`radacctid`),
       UNIQUE KEY `acctuniqueid` (`acctuniqueid`),
       KEY `username` (`username`),
       KEY `framedipaddress` (`framedipaddress`),
       KEY `acctsessionid` (`acctsessionid`),
       KEY `acctsessiontime` (`acctsessiontime`),
       KEY `acctstarttime` (`acctstarttime`),
       KEY `acctinterval` (`acctinterval`),
       KEY `acctstoptime` (`acctstoptime`),
       KEY `nasipaddress` (`nasipaddress`),
       KEY `callingstationid` (`callingstationid`) USING BTREE
     ) ENGINE=InnoDB AUTO_INCREMENT=14270573 DEFAULT CHARSET=utf8      COLLATE=utf8_unicode_ci;
    

    显示变量,如“sql_mode”

    “sql_mode”,“NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION”

    添加2:

    这是最后一个按建议完美运行的查询@Rick James

     UPDATE radacct SET 
                radacct.AcctStopTime=NOW(),
                radacct.AcctTerminateCause='Stale-Session'
            WHERE (  NOW() - interval (60*6+60*6) second  >  radacct.acctstarttime + interval radacct.acctsessiontime second  )
                AND (AcctStopTime = '0000-00-00 00:00:00' OR AcctStopTime IS NULL)
    

    谢谢

    2 回复  |  直到 8 年前
        1
  •  1
  •   Rick James    8 年前

    避免减法,只在时间戳中工作:

    WHERE  radacct.acctstarttime + INTERVAL radacct.acctsessiontime SECOND
         < NOW() - INTERVAL 12 MINUTE
    

    (在我看来,它更具可读性)

    此“复合”索引 可以 帮助性能:

    INDEX(acctstarttime, acctsessiontime, AcctStopTime)
    

    如果您有性能问题,请考虑规范化宽而重复的列。

        2
  •  1
  •   Bernd Buffen    8 年前

    这不是一个答案,但我不能在评论中格式化它。

    您使用的是哪种MariaDB版本?

    错误处理

    在MySQL和MariaDB 5.3之前版本中,UNIX_TIMESTAMP()的参数错误 返回0。从MariaDB 5.3开始,错误返回NULL UNIX_TIMESTAMP()的参数。

    兼容性

    正如您在上面的示例中看到的, UNIX_TIMESTAMP(常量日期字符串)在MariaDB 5.3中返回 MariaDB 5.2和MySQL返回6位小数的时间戳 没有小数。如果您使用 UNIX_TIMESTAMP()作为分区函数。您可以使用 地板(UNIX_TIMESTAMP(..)) 或将日期字符串更改为日期 数量,如200801000000。

    https://mariadb.com/kb/en/mariadb/unix_timestamp/

    尝试此操作以查找错误行

    检查此项-给出错误

    SELECT CAST(0 AS UNSIGNED) - 1;
    

    将sql_mode设置为

    SET sql_mode='NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_UNSIGNED_SUBTRACTION';
    

    选择铸造(0为未指定)-1;
    

    查询以查找错误的行

    SELECT *
    FROM radacct
    WHERE ((UNIX_TIMESTAMP(NOW()) - (UNIX_TIMESTAMP(radacct.acctstarttime) + radacct.acctsessiontime)) < 0
    AND (AcctStopTime = '0000-00-00 00:00:00' OR AcctStopTime IS NULL)