我有一个加载大量数据的灯具,而且我遇到这个错误的所有时间:
致命错误:允许的内存大小为2147483648个字节(已尝试 分配16777224个字节) /var/www/html/platform-cm/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/DebugStack.php 第65行
[Symfony \ Component \ Debug \ Exception \ OutOfMemoryException]错误: 允许的内存大小为2147483648个字节(尝试分配) 16777224字节)
经过研究后我发现this帖子,我读到日志记录可能是问题的原因,因为AppKernel
默认情况下调试设置为true,然后SQL命令存储在每次迭代的内存。
第一次尝试没有在AppKernel
禁用调试时运行命令为:
doctrine:fixtures:load --no-debug
但是由于同样的错误,我没有好运。
第二次尝试是在config_dev.yml
禁用调试,但不建议这样做,因为我正在获取每个日志,但两者都没有。
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
# console:
# type: console
# bubble: false
# verbosity_levels:
# VERBOSITY_VERBOSE: INFO
# VERBOSITY_VERY_VERBOSE: DEBUG
# channels: ["!doctrine"]
# console_very_verbose:
# type: console
# bubble: false
# verbosity_levels:
# VERBOSITY_VERBOSE: NOTICE
# VERBOSITY_VERY_VERBOSE: NOTICE
# VERBOSITY_DEBUG: DEBUG
# channels: ["doctrine"]
所以,这就是我的装置的样子:
class LoadMsisdn extends AbstractFixture implements OrderedFixtureInterface
{
public function getOrder()
{
return 13;
}
public function load(ObjectManager $manager)
{
$content = file_get_contents('number.txt');
$numbers = explode(',', $content);
shuffle($numbers);
foreach ($numbers as $key => $number) {
$msisdn = new Msisdn();
$msisdn->setMsisdn($number);
$msisdn->setBlocked((rand(1, 1000) % 10) < 7);
$msisdn->setOperator($this->getReference('operator-' . rand(45, 47)));
$this->addReference('msisdn-' . $key, $msisdn);
$manager->persist($msisdn);
}
$manager->flush();
}
}
如果需要从EntityManager
执行此操作,如何在相同帖子的答案中显示,请如何禁用记录器?
$em->getConnection()->getConfiguration()->setSQLLogger(null);
答案 0 :(得分:8)
传递给load
方法的对象管理器是实体管理器的实例(Doctrine\Common\Persistence\ObjectManager
只是实体/文档/等管理器实现的接口)。
这意味着您可以使用与问题中相同的命令来使SQL记录器无效,如..
$manager->getConnection()->getConfiguration()->setSQLLogger(null);
需要注意的一点是,DBAL连接的默认日志记录设置为%kernel.debug%
,这意味着,除非您在配置中覆盖它,否则日志记录应仅在dev
环境中进行。我可以看到您尝试使用--no-debug
选项,但我只能假设,因为记录器设置为during the container compilation,它不会将其取消设置为未重建的容器。
答案 1 :(得分:0)
我不确定这是否有助于解决内存限制问题,但您也可以尝试通过YAML配置(更舒适地)更改日志记录:
(与您的注释代码相同)
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: ["!doctrine"] # "!event", "!php"
在services.yaml
中,为默认的Doctor记录器设置类:
doctrine.dbal.logger:
class: App\ORM\Doctrine\DBAL\Logging\DummySQLLogger
并在doctrine.yaml
中启用它:
doctrine:
dbal:
driver: 'pdo_mysql'
logging: true
自定义记录器必须实现接口Doctrine\DBAL\Logging\SQLLogger
。可以将具体方法startQuery
和stopQuery
保留为空,以跳过日志记录。或仅使用error_log
(例如我的情况)。
我不确定这是否可以防止超出内存的问题。最终增加PHP_MEMORY_LIMIT
(如果环境支持,则通过env变量,或者通过ini_set()
)。