Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

PHP mysql_stmt ::fetch () cung cấp cho PHP bộ nhớ lỗi nghiêm trọng

Bạn sẽ thấy rằng điều này đang xảy ra chỉ khi @statusNULL hoặc một chuỗi.

Vấn đề gấp đôi:

  1. Không giống như biến cục bộ , MySQL biến người dùng hỗ trợ một tập hợp rất hạn chế các kiểu dữ liệu:

    Tài liệu không đề cập đến rằng kiểu dữ liệu thực tế được sử dụng tương ứng là BIGINT , DECIMAL(65,30) , DOUBLE , LONGBLOB , LONGTEXTLONGBLOB . Về điều cuối cùng, sách hướng dẫn ít nhất giải thích:

    Bộ nhớ của ba kiểu dữ liệu đầu tiên (tức là cho các giá trị số nguyên, số thập phân và dấu phẩy động) yêu cầu tương ứng là 8, 30 và 8 byte. Các kiểu dữ liệu khác (tức là cho chuỗi và NULL giá trị) yêu cầu (tối đa) 4 gigabyte bộ nhớ.

  2. Vì bạn đang sử dụng phiên bản PHP trước v5.4.0, trình điều khiển MySQL mặc định là libmysql , với siêu dữ liệu loại cột chỉ có sẵn từ máy chủ khi liên kết dữ liệu — vì vậy MySQLi cố gắng phân bổ đủ bộ nhớ để giữ mọi giá trị có thể (ngay cả khi bộ đệm đầy đủ cuối cùng không được yêu cầu); do đó NULL - và các biến người dùng có giá trị chuỗi, có kích thước tối đa có thể là 4GiB, khiến PHP vượt quá giới hạn bộ nhớ mặc định của nó (là 128MiB kể từ phiên bản PHP v5.2.0).

Các tùy chọn của bạn bao gồm:

  • Ghi đè kiểu dữ liệu cột trong định nghĩa bảng:

    DROP TEMPORARY TABLE IF EXISTS tmp_table;
    CREATE TEMPORARY TABLE tmp_table (
      status VARCHAR(2)
    ) SELECT @status AS status;
    
  • Rõ ràng truyền biến người dùng thành một kiểu dữ liệu cụ thể hơn:

    DROP TEMPORARY TABLE IF EXISTS tmp_table;
    CREATE TEMPORARY TABLE tmp_table
      SELECT CAST(@status AS CHAR(2)) AS status;
    
  • Sử dụng các biến cục bộ, được khai báo với kiểu dữ liệu rõ ràng:

    DECLARE status VARCHAR(2) DEFAULT @status;
    DROP TEMPORARY TABLE IF EXISTS tmp_table;
    CREATE TEMPORARY TABLE tmp_table
      SELECT status;
    
  • Khắc phục sự cố bằng cách gọi mysqli_stmt::store_result() trước mysqli_stmt::bind_result() , điều này khiến tập kết quả được lưu trữ trong libmysql (nằm ngoài giới hạn bộ nhớ của PHP) và sau đó PHP sẽ chỉ cấp phát bộ nhớ thực tế cần thiết để lưu giữ bản ghi khi tìm nạp nó:

    $stmt->execute();
    $stmt->store_result();
    $stmt->bind_result( $status );
    $stmt->fetch();
    
  • Nâng cao giới hạn bộ nhớ của PHP để nó có thể cung cấp khả năng phân bổ bộ đệm 4GiB (mặc dù người ta nên biết những tác động đối với tài nguyên phần cứng khi làm như vậy) - ví dụ:để loại bỏ hoàn toàn các ràng buộc bộ nhớ (mặc dù hãy lưu ý về các tác dụng phụ tiêu cực tiềm ẩn khi làm điều này, ví dụ:từ rò rỉ bộ nhớ chính hãng):

    ini_set('memory_limit', '-1');
    
  • Biên dịch lại PHP, được định cấu hình để sử dụng trình điều khiển mysqlnd gốc (được bao gồm trong PHP kể từ v5.3.0, nhưng không được định cấu hình làm mặc định cho đến PHP v5.4.0) thay vì libmysql:

    ./configure --with-mysqli=mysqlnd
    
  • Nâng cấp lên PHP v5.4.0 trở lên để mysqlnd được sử dụng theo mặc định.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. JSON_SET () - Chèn hoặc cập nhật giá trị trong tài liệu JSON trong MySQL

  2. Cài đặt MySQL 5.6 trên Ubuntu 20.04

  3. Sự khác biệt giữa Mã hóa và đối chiếu?

  4. codeigniter mysql trái tham gia bao gồm chọn

  5. GIỮA truy vấn sử dụng JDBC với MySQL