mysql - 在进程中间从脚本中释放内存

标签 mysql perl memory memory-leaks

我有一个脚本,可以运行多年备份中的数百甚至数千个表,以更改人们要求的内容。

从本月开始,它开始使用过多的 RAM,以至于服务器杀死了它。

那么,有没有一种方法可以在每次从数据库中提取数据并让我的 Perl 脚本运行数据、搜索要更改的信息后,在提取下一个数据之前重置 RAM?

所以基本上它会重置刚刚提取的数据,以便所有这些数据都不在 RAM 中?

我在 2007 年创建了这个东西,我当然希望我做得方式有所不同,但这需要进行重大修改和更新,而我现在无法做到这一点。也许在将来。但到目前为止,我还不能这样做。

所以我需要一种方法来防止这种情况发生。

如果您知道清除该内存的方法,请告诉我。

如果您能给我指路,请先谢谢您。

--- 更新 ---- 添加了实际拉取所有数据的部分网站代码 ----

        $_startingTime = time();
        $dbh->do(qq{update `tun_changes` set `status` = "working", `startedT` = ? where `unid` = ?}, undef, $_startingTime, $_tr->{unid});
        $sth2 = $dbh->prepare(qq{select * from `allmembers` where `mId` = ?});
        $sth2->execute($_tr->{mId});
        $_tregmem = $sth2->fetchrow_hashref();
        $sth2->finish();
        $dbh->do(qq{delete from `sessions` where `id` = "$_tregmem->{last_sessid}"}); #kill their logged in session, so it does not lock them up if they are logged in when we change their username...
        $_un = $_tregmem->{tusername};
        $_cust_id = $_tr->{mId};
        $_notfinished = 0;
        $_newUname = lc($_tr->{newun});
        $_csusername = $_tr->{csusername};# if customer service rep...
        $_count = 0;
        $_changeFailed = 0;
        $_changed = 0;
        $_debugChg = 1;
        if($_debugChg) {
            open(DBG,">>/home$_website_username/required/files/urgent/all_chg_uname_debug_track.txt");
            seek(DBG,0,2);
            print DBG "Checking Table at " . Format_Date_For_Viewing($_startingTime,"") . " - indented two lines at least for this record.... until _end_ is shown\n";
        }
        @_mb = $dbh->tables;
        $_tablesAffected = 0;
        foreach $_k (@_mb) {
            $_sql = "select * from $_k";
            if($_debugChg) {
                print DBG "\tTable $_k (" . duration(time() - $_startingTime) . " into action)\n";
            }
            $sth2 = $dbh->prepare($_sql);
            $sth2->execute();
            @_mb2 = @{$sth2->{NAME}};
            foreach $_k2 (@_mb2) {
                if($_debugChg) {
                    print DBG "\t\tColumn $_k2";
                }
                if($_k2 =~ /tusername/i) {
                    if($_debugChg) {
                        print DBG "\t Checking for username entries in $_k2\n";
                    }
                    $_updated = $dbh->do(qq{update $_k SET `$_k2` = ? WHERE `$_k2` = ?}, undef, $_newUname, $_un);
                    if($_updated) {
                        $_changed += $_updated;
                    } else {
                        $_changeFailed += $_updated;
                    }
                } else {
                    if($_debugChg) {
                        print DBG " - Not UN\n";
                    }
                }
            }
            $sth2->finish();
            if($_debugChg) {
                print DBG "\n";
            }
        }
        if($_debugChg) {
            print DBG "\nFinished - Duration was: " . duration(time() - $_startingTime) . "\n";
            print DBG "\n_end_\n\n";
            close(DBG);
        }

我留下了调试代码,以便在出现故障时可以看到做了什么。

最佳答案

这里的问题并不明显。看起来并不存在明显的内存泄漏,因此尝试释放分配的内存可能不是您需要解决的问题。理论上,Perl 可以在运行时将内存释放回操作系统,但必须满足某些条件,并且根据我的经验,这种情况并不常见。

连接到数据库后设置$dbh->{mysql_use_result} = 1;可能会有很大帮助。

这改变了 DBI(实际上是 libmysqlclient)从套接字读取传入数据的方式,导致每次调用 fetchrow* 方法时它都会根据需要读取数据,而不是先将其全部缓冲到内存中,然后一次从内存中已有的内容中向您提供一行,这是默认行为。

DBD::mysql 和底层库可能是负责大量内存使用的实体,因此值得一试。

关于mysql - 在进程中间从脚本中释放内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37106211/

相关文章:

apache - tomcat可以配置为apache的代理吗?

excel - 如何使用 Excel::Writer::XLSX 创建一个表,其中插入行复制列的公式?

iphone - 从代码中模拟内存警告,可能吗?

java - Java 程序性能的 CPU 和内存使用直方图

php - Doctrine 生成的 MySQL Schema 位于目录结构中的什么位置?

Mysql 查询从多个范围中进行选择

mysql - 如何在 MySql Workbench 中禁用 INVISIBLE 索引选项?

Perl 和复杂的 SOAP 请求

c++ - 使用分配器替代 malloc()/free()?

mysql - 在子查询中显示表状态?