sql >> データベース >  >> RDS >> Mysql

PHP mysql_stmt ::fetch()は、PHPの致命的なエラーメモリを使い果たします

    これはのみ発生していることがわかります @statusの場合 NULLです または文字列。

    問題は2つあります:

    1. ローカル変数 とは異なります 、MySQL ユーザー変数 非常に限られたデータ型のセットをサポートします:

      ドキュメントには、実際のデータ型 については記載されていません。 使用されるのはそれぞれBIGINTDECIMAL(65,30)DOUBLELONGBLOBLONGTEXT およびLONGBLOB 。最後のものに関しては、マニュアルは少なくとも説明しています:

      ストレージ これらのデータ型の最初の3つ(つまり、整数、10進数、および浮動小数点値の場合)には、それぞれ8、30、および8バイトが必要です。その他のデータ型(つまり、文字列とNULLの場合 値)require(最大)4ギガバイト ストレージの。

    2. v5.4.0より前のバージョンのPHPを使用しているため、デフォルトのMySQLドライバーは libmysql 、データバインディング時にサーバーから利用できるのは列タイプのメタデータのみです。したがって、MySQLiは、すべての可能な値を保持するのに十分なメモリを割り当てようとします(最終的にフルバッファが必要ない場合でも)。したがって、NULL -および文字列値のユーザー変数は、可能な最大サイズが4GiBであるため、PHPがデフォルトのメモリ制限(PHP v5.2.0以降は128MiB)を超えます。

    オプションは次のとおりです。

    • テーブル定義の列データ型をオーバーライドする:

      DROP TEMPORARY TABLE IF EXISTS tmp_table;
      CREATE TEMPORARY TABLE tmp_table (
        status VARCHAR(2)
      ) SELECT @status AS status;
      
    • 明示的にキャスト より具体的なデータ型へのユーザー変数:

      DROP TEMPORARY TABLE IF EXISTS tmp_table;
      CREATE TEMPORARY TABLE tmp_table
        SELECT CAST(@status AS CHAR(2)) AS status;
      
    • 明示的なデータ型で宣言されているローカル変数の使用:

      DECLARE status VARCHAR(2) DEFAULT @status;
      DROP TEMPORARY TABLE IF EXISTS tmp_table;
      CREATE TEMPORARY TABLE tmp_table
        SELECT status;
      
    • mysqli_stmt::store_result()を呼び出して問題を回避する mysqli_stmt::bind_result() 、これにより、結果セットがlibmysqlに(PHPのメモリ制限外で)格納され、PHPは、レコードのフェッチ時にレコードを保持するために必要な実際のメモリのみを割り当てます。

      $stmt->execute();
      $stmt->store_result();
      $stmt->bind_result( $status );
      $stmt->fetch();
      
    • PHPのメモリ制限 を引き上げる 4GiBバッファの割り当てに対応できるようにするため(ただし、ハードウェアリソースへの影響に注意する必要があります)、たとえば、メモリ制約を完全に削除します(ただし、これを行うことによる潜在的な悪影響に注意してください。例:本物のメモリリークから):

      ini_set('memory_limit', '-1');
      
    • ネイティブmysqlndドライバー を使用するように構成されたPHPの再コンパイル (v5.3.0以降はPHPに含まれていますが、PHP v5.4.0まではデフォルトとして構成されていません)libmysqlの代わりに:

      ./configure --with-mysqli=mysqlnd
      
    • mysqlndがデフォルトで使用されるようにPHPv5.4.0以降にアップグレードします。




    1. JavaMySQLタイムスタンプのタイムゾーンの問題

    2. SQLServerのGROUPINGおよびGROUPING_ID関数について

    3. SQLクエリでの一重引用符

    4. SQL Serverテーブル:@、#、および##の違いは何ですか?