从 php 5.6 插入 mariadb 10.1 不插入一些行
Insert from php 5.6 into mariadb 10.1 not inserting some rows
我有一个测试脚本的奇怪问题,从昨天开始我就很难解决。
我的 php 脚本是这样工作的:
我有一个 xml 文件,其中包含大约 1000 个项目,每个项目大约有 10 个字段。
我 运行 一个读取 xml 的 php 脚本,用 mysqli 转义每个字段并分批插入 mariadb 10.1(目前正在一个接一个地执行)。
有趣的是,它插入了大约 960 行没有问题,但是大约有 20 到 30 行没有插入,这就是问题所在。
当我说它没有插入时,我的意思是即使在 运行 运行脚本几分钟后,我转到 phpmyadmin(或命令行)也找不到那些行全部(按 ID 或唯一字段、名称等查询)。
如果我打印查询并通过 phpmyadmin 插入它,它会毫无问题地进入。
但是,当我通过 php 插入它们时,它显示它已被插入,甚至 returns id(没有错误):
printf ("New Record has id %d.\n", $mysqli->insert_id);
所以我获取了 id,转到 phpmyadmin,那里没有那个 id(但自动增量增加了)。
更有趣的是,如果我在 php 上按 id 查询,它会显示结果...但如果我 select 所有行(也在 [=51] 上,它不在列表中=]).
所以当我通过 id select 时,行在 php 上,但是通过命令行或 phpmyadmin.
不存在该 id
其中一些记录最终会在几分钟内出现,但大多数甚至在几个小时后仍未显示在 phpmyadmin 上。
就像我的一些插入正在排队,一些插入并被丢弃,而另一些则没有任何问题。
这是 php 或 mariadb 10.1 的新功能或错误吗?
我将进一步调试,但这里有一些代码:
# use dom and xpath
$xml = simplexml_load_file($tmp);
if(is_object($xml)) { echo "XML is an object...<br />"; }
foreach ($xml->job as $r) {
if(isset($r->uid)) {
# filter data
$uid = $mysqli->real_escape_string(trim($r->uid));
$date = $mysqli->real_escape_string(date('Y-m-d H:i:s'));
$title = $mysqli->real_escape_string(trim($r->title));
$descr = $mysqli->real_escape_string(trim($r->descr));
$company = $mysqli->real_escape_string(trim($r->company));
$loc = $mysqli->real_escape_string(trim($r->loc));
$contact = $mysqli->real_escape_string(trim($r->contact));
$jobs[$uid] = "('$uid', '$date', '$title', '$descr', '$company', '$loc', '$contact')";
echo "<br />Found item: $uid / <b>$title</b>";
}
}
# insert in chunks of 10 (also tried REPLACE INTO with same results)
if(count($jobs) > '0') {
echo '<br />Inserting data...<br />';
$chunks = array_chunk($jobs, 10); foreach ($chunks as $chunk) { $insert = implode(", ", $chunk);
$result = $mysqli->query("INSERT INTO core_jobs_tmp (uid, date, title, descr, company, loc, contact) VALUES $insert");
$nid = $mysqli->insert_id;
printf ("New Record has id %d.\n", $mysqli->insert_id);
# check if it's there (debug: usually it's returns the result correctly)
$sql = $mysqli->query("SELECT * FROM core_jobs_tmp WHERE id = '$nid'");
if (mysqli_num_rows($sql) > '0') { while($r = mysqli_fetch_array($sql)) { echo '<br />'.$r['title'].'<br />'; } }
}
}
示例 xml 有 2 个项目无法从 php:
插入
<?xml version='1.0' encoding='UTF-8'?>
<ads>
<job>
<url><![CDATA[someurlhere]]></url>
<uid><![CDATA[42f4505cdb6c637777e7cdfd2ab9f354]]></uid>
<company><![CDATA[Empregos Work]]></company>
<site><![CDATA[indeed.com.br]]></site>
<country><![CDATA[br]]></country>
<date><![CDATA[2016-01-30]]></date>
<loc><![CDATA[Rio de Janeiro, RJ]]></loc>
<title><![CDATA[Assistente Administrativo Júnior]]></title>
<descr><![CDATA[Empresa:
Apenas usuários logados
Cargo:
Assistente Administrativo Júnior
Nível do cargo:
Nível Operacional
Contrato:
Temporário
Sexo:
Indiferente
Quantidade:
Salário:
R$ 970,00
Cidade:
RIO DE JANEIRO
Local de Trabalho:
não disponível
Benefícios:
Vale transporte
Requer Experiencia em:
Experiência anterior na área administrava e atendimento ao cliente
Formação Academica:
Ensino Médio Completo
Competências /
Características Pessoais: OBS: Oportunidade Temporária 3 meses
Atividades:
Atendimento ao cliente, conferência de documentos e lançamento de dados no sistema próprio da empresa.
Disponibilidade para viagens:
É necessário ter carro próprio:]]></descr>
<contact><![CDATA[someurlhere]]></contact>
</job>
<job>
<url><![CDATA[someurlhere]]></url>
<uid><![CDATA[02b5af5d2cc279890aae6f12db7003df]]></uid>
<company><![CDATA[Empregos Work]]></company>
<site><![CDATA[indeed.com.br]]></site>
<country><![CDATA[br]]></country>
<date><![CDATA[2016-01-30]]></date>
<loc><![CDATA[Rio de Janeiro, RJ]]></loc>
<title><![CDATA[Assistente Comercial]]></title>
<descr><![CDATA[Empresa:
Apenas usuários logados
Cargo:
Assistente Comercial
Nível do cargo:
Nível Operacional
Contrato:
Efetivo
Sexo:
Indiferente
Quantidade:
Salário:
R$ 2.300,00
Cidade:
RIO DE JANEIRO
Local de Trabalho:
não disponível
Benefícios:
Vale transporte, vale refeição, plano de saúde e odontológico.
Requer Experiencia em:
Experiência anterior na função.
Formação Academica:
Possuir ensino superior completo ou em andamento
Atividades:
Venda interna e externa de serviços.
Disponibilidade para viagens:
É necessário ter carro próprio:]]></descr>
<contact><![CDATA[someurlhere]]></contact>
</job>
</ads>
Table结构:
CREATE TABLE IF NOT EXISTS `core_jobs_tmp` (
`id` int(11) NOT NULL,
`uid` varchar(64) NOT NULL,
`date` datetime NOT NULL,
`title` varchar(128) NOT NULL DEFAULT '',
`descr` mediumtext NOT NULL,
`company` varchar(128) NOT NULL,
`loc` varchar(128) NOT NULL,
`state` varchar(128) NOT NULL,
`city` varchar(128) NOT NULL,
`contact` varchar(255) NOT NULL,
`paid` int(2) unsigned NOT NULL DEFAULT '0'
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
ALTER TABLE `core_jobs_tmp`
ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `uid` (`uid`), ADD KEY `date` (`date`), ADD KEY `paid` (`paid`), ADD FULLTEXT KEY `title` (`title`,`descr`,`company`,`loc`);
ALTER TABLE `core_jobs_tmp`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=1;
还有我的 mariadb 配置:
[mysql]
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysqld]
user = mysql
default-storage-engine = InnoDB
socket = /var/run/mysqld/mysqld.sock
pid-file = /var/run/mysqld/mysqld.pid
bind-address = 127.0.0.1
character-set-server = utf8
collation-server = utf8_general_ci
# MyISAM #
key-buffer-size = 8M
myisam-recover-options = FORCE,BACKUP
# SAFETY #
max-allowed-packet = 32M
max-connect-errors = 1000000000
explicit_defaults_for_timestamp = 1
# DATA STORAGE #
basedir = /usr
tmpdir = /tmp
datadir = /var/lib/mysql/
# BINARY LOGGING #
log-bin = /var/lib/mysql/mysql-bin
expire-logs-days = 7
sync-binlog = 1
# CACHES AND LIMITS #
tmp-table-size = 128M
max-heap-table-size = 128M
query-cache-type = 0
query-cache-size = 0
max-connections = 1024
thread-cache-size = 1024
wait_timeout = 3600
open-files-limit = 65535
table-definition-cache = 4096
table-open-cache = 4096
# INNODB #
innodb_thread_concurrency = 0
innodb-flush-method = O_DIRECT
innodb-log-files-in-group = 2
innodb-log-file-size = 384M
innodb-flush-log-at-trx-commit = 0
innodb-file-per-table = 1
innodb-buffer-pool-size = 1800M
# LOGGING #
log-error = /var/log/mysql/mysql-error.log
long_query_time = 2
log-queries-not-using-indexes = 0
slow-query-log = 1
slow-query-log-file = /var/log/mysql/mysql-slow.log
# Fine Tuning #
thread_stack = 256K
ft_min_word_len = 3
[mysqldump]
quick
quote-names
max_allowed_packet = 512M
一些服务器信息:
Server version: 10.1.10-MariaDB-1~jessie-log - mariadb.org binary distribution
Server charset: UTF-8 Unicode (utf8)
Database client version: libmysql - 5.6.24
PHP extension: mysqli
phpMyAdmin Version information: 4.2.12deb2+deb8u1
php -v PHP 5.6.14-0+deb8u1 (cli) (built: Oct 4 2015 16:13:10)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
其实我已经解决了。
数据库或安装以某种方式损坏。
我将数据库 mysqldump 到 mariadb 10.0 上的另一个数据库服务器,它正在运行。
所以我清除并重新安装了 mariadb 10.1 和 mysqldump 它从 mariadb 10 回到 mariadb 10.1,它现在可以工作了。奇怪的问题,但有效。
我有一个测试脚本的奇怪问题,从昨天开始我就很难解决。
我的 php 脚本是这样工作的: 我有一个 xml 文件,其中包含大约 1000 个项目,每个项目大约有 10 个字段。 我 运行 一个读取 xml 的 php 脚本,用 mysqli 转义每个字段并分批插入 mariadb 10.1(目前正在一个接一个地执行)。
有趣的是,它插入了大约 960 行没有问题,但是大约有 20 到 30 行没有插入,这就是问题所在。
当我说它没有插入时,我的意思是即使在 运行 运行脚本几分钟后,我转到 phpmyadmin(或命令行)也找不到那些行全部(按 ID 或唯一字段、名称等查询)。
如果我打印查询并通过 phpmyadmin 插入它,它会毫无问题地进入。
但是,当我通过 php 插入它们时,它显示它已被插入,甚至 returns id(没有错误):
printf ("New Record has id %d.\n", $mysqli->insert_id);
所以我获取了 id,转到 phpmyadmin,那里没有那个 id(但自动增量增加了)。
更有趣的是,如果我在 php 上按 id 查询,它会显示结果...但如果我 select 所有行(也在 [=51] 上,它不在列表中=]).
所以当我通过 id select 时,行在 php 上,但是通过命令行或 phpmyadmin.
不存在该 id其中一些记录最终会在几分钟内出现,但大多数甚至在几个小时后仍未显示在 phpmyadmin 上。
就像我的一些插入正在排队,一些插入并被丢弃,而另一些则没有任何问题。
这是 php 或 mariadb 10.1 的新功能或错误吗?
我将进一步调试,但这里有一些代码:
# use dom and xpath
$xml = simplexml_load_file($tmp);
if(is_object($xml)) { echo "XML is an object...<br />"; }
foreach ($xml->job as $r) {
if(isset($r->uid)) {
# filter data
$uid = $mysqli->real_escape_string(trim($r->uid));
$date = $mysqli->real_escape_string(date('Y-m-d H:i:s'));
$title = $mysqli->real_escape_string(trim($r->title));
$descr = $mysqli->real_escape_string(trim($r->descr));
$company = $mysqli->real_escape_string(trim($r->company));
$loc = $mysqli->real_escape_string(trim($r->loc));
$contact = $mysqli->real_escape_string(trim($r->contact));
$jobs[$uid] = "('$uid', '$date', '$title', '$descr', '$company', '$loc', '$contact')";
echo "<br />Found item: $uid / <b>$title</b>";
}
}
# insert in chunks of 10 (also tried REPLACE INTO with same results)
if(count($jobs) > '0') {
echo '<br />Inserting data...<br />';
$chunks = array_chunk($jobs, 10); foreach ($chunks as $chunk) { $insert = implode(", ", $chunk);
$result = $mysqli->query("INSERT INTO core_jobs_tmp (uid, date, title, descr, company, loc, contact) VALUES $insert");
$nid = $mysqli->insert_id;
printf ("New Record has id %d.\n", $mysqli->insert_id);
# check if it's there (debug: usually it's returns the result correctly)
$sql = $mysqli->query("SELECT * FROM core_jobs_tmp WHERE id = '$nid'");
if (mysqli_num_rows($sql) > '0') { while($r = mysqli_fetch_array($sql)) { echo '<br />'.$r['title'].'<br />'; } }
}
}
示例 xml 有 2 个项目无法从 php:
插入<?xml version='1.0' encoding='UTF-8'?>
<ads>
<job>
<url><![CDATA[someurlhere]]></url>
<uid><![CDATA[42f4505cdb6c637777e7cdfd2ab9f354]]></uid>
<company><![CDATA[Empregos Work]]></company>
<site><![CDATA[indeed.com.br]]></site>
<country><![CDATA[br]]></country>
<date><![CDATA[2016-01-30]]></date>
<loc><![CDATA[Rio de Janeiro, RJ]]></loc>
<title><![CDATA[Assistente Administrativo Júnior]]></title>
<descr><![CDATA[Empresa:
Apenas usuários logados
Cargo:
Assistente Administrativo Júnior
Nível do cargo:
Nível Operacional
Contrato:
Temporário
Sexo:
Indiferente
Quantidade:
Salário:
R$ 970,00
Cidade:
RIO DE JANEIRO
Local de Trabalho:
não disponível
Benefícios:
Vale transporte
Requer Experiencia em:
Experiência anterior na área administrava e atendimento ao cliente
Formação Academica:
Ensino Médio Completo
Competências /
Características Pessoais: OBS: Oportunidade Temporária 3 meses
Atividades:
Atendimento ao cliente, conferência de documentos e lançamento de dados no sistema próprio da empresa.
Disponibilidade para viagens:
É necessário ter carro próprio:]]></descr>
<contact><![CDATA[someurlhere]]></contact>
</job>
<job>
<url><![CDATA[someurlhere]]></url>
<uid><![CDATA[02b5af5d2cc279890aae6f12db7003df]]></uid>
<company><![CDATA[Empregos Work]]></company>
<site><![CDATA[indeed.com.br]]></site>
<country><![CDATA[br]]></country>
<date><![CDATA[2016-01-30]]></date>
<loc><![CDATA[Rio de Janeiro, RJ]]></loc>
<title><![CDATA[Assistente Comercial]]></title>
<descr><![CDATA[Empresa:
Apenas usuários logados
Cargo:
Assistente Comercial
Nível do cargo:
Nível Operacional
Contrato:
Efetivo
Sexo:
Indiferente
Quantidade:
Salário:
R$ 2.300,00
Cidade:
RIO DE JANEIRO
Local de Trabalho:
não disponível
Benefícios:
Vale transporte, vale refeição, plano de saúde e odontológico.
Requer Experiencia em:
Experiência anterior na função.
Formação Academica:
Possuir ensino superior completo ou em andamento
Atividades:
Venda interna e externa de serviços.
Disponibilidade para viagens:
É necessário ter carro próprio:]]></descr>
<contact><![CDATA[someurlhere]]></contact>
</job>
</ads>
Table结构:
CREATE TABLE IF NOT EXISTS `core_jobs_tmp` (
`id` int(11) NOT NULL,
`uid` varchar(64) NOT NULL,
`date` datetime NOT NULL,
`title` varchar(128) NOT NULL DEFAULT '',
`descr` mediumtext NOT NULL,
`company` varchar(128) NOT NULL,
`loc` varchar(128) NOT NULL,
`state` varchar(128) NOT NULL,
`city` varchar(128) NOT NULL,
`contact` varchar(255) NOT NULL,
`paid` int(2) unsigned NOT NULL DEFAULT '0'
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
ALTER TABLE `core_jobs_tmp`
ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `uid` (`uid`), ADD KEY `date` (`date`), ADD KEY `paid` (`paid`), ADD FULLTEXT KEY `title` (`title`,`descr`,`company`,`loc`);
ALTER TABLE `core_jobs_tmp`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=1;
还有我的 mariadb 配置:
[mysql]
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysqld]
user = mysql
default-storage-engine = InnoDB
socket = /var/run/mysqld/mysqld.sock
pid-file = /var/run/mysqld/mysqld.pid
bind-address = 127.0.0.1
character-set-server = utf8
collation-server = utf8_general_ci
# MyISAM #
key-buffer-size = 8M
myisam-recover-options = FORCE,BACKUP
# SAFETY #
max-allowed-packet = 32M
max-connect-errors = 1000000000
explicit_defaults_for_timestamp = 1
# DATA STORAGE #
basedir = /usr
tmpdir = /tmp
datadir = /var/lib/mysql/
# BINARY LOGGING #
log-bin = /var/lib/mysql/mysql-bin
expire-logs-days = 7
sync-binlog = 1
# CACHES AND LIMITS #
tmp-table-size = 128M
max-heap-table-size = 128M
query-cache-type = 0
query-cache-size = 0
max-connections = 1024
thread-cache-size = 1024
wait_timeout = 3600
open-files-limit = 65535
table-definition-cache = 4096
table-open-cache = 4096
# INNODB #
innodb_thread_concurrency = 0
innodb-flush-method = O_DIRECT
innodb-log-files-in-group = 2
innodb-log-file-size = 384M
innodb-flush-log-at-trx-commit = 0
innodb-file-per-table = 1
innodb-buffer-pool-size = 1800M
# LOGGING #
log-error = /var/log/mysql/mysql-error.log
long_query_time = 2
log-queries-not-using-indexes = 0
slow-query-log = 1
slow-query-log-file = /var/log/mysql/mysql-slow.log
# Fine Tuning #
thread_stack = 256K
ft_min_word_len = 3
[mysqldump]
quick
quote-names
max_allowed_packet = 512M
一些服务器信息:
Server version: 10.1.10-MariaDB-1~jessie-log - mariadb.org binary distribution
Server charset: UTF-8 Unicode (utf8)
Database client version: libmysql - 5.6.24
PHP extension: mysqli
phpMyAdmin Version information: 4.2.12deb2+deb8u1
php -v PHP 5.6.14-0+deb8u1 (cli) (built: Oct 4 2015 16:13:10)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
其实我已经解决了。 数据库或安装以某种方式损坏。 我将数据库 mysqldump 到 mariadb 10.0 上的另一个数据库服务器,它正在运行。 所以我清除并重新安装了 mariadb 10.1 和 mysqldump 它从 mariadb 10 回到 mariadb 10.1,它现在可以工作了。奇怪的问题,但有效。