Tại sao MySQL nói tôi hết bộ nhớ?


9

Tôi đã cố gắng thực hiện một số lượng khá lớn INSERT...SELECTtrong MySQL với JDBC và tôi đã có một ngoại lệ sau:

Exception in thread "main" java.sql.SQLException: Out of memory (Needed 1073741824 bytes)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)

Vì tôi không thực sự trả về một đối tượng Kết quả, tôi nghĩ rằng không gian heap Java không phải là một vấn đề. Tuy nhiên, dù sao thì tôi cũng đã cố gắng và nó không được tốt. Sau đó tôi đã cố gắng thực hiện câu lệnh trong MySQL Workbench và về cơ bản tôi cũng nhận được điều tương tự:

Error Code 5: Out of memory (Needed 1073741816 bytes)

Tôi nên có nhiều RAM để hoàn thành các thao tác này (đủ để phù hợp với toàn bộ bảng tôi đang chọn), nhưng tôi đoán có nhiều cài đặt khác nhau tôi cần điều chỉnh để tận dụng tất cả bộ nhớ của mình. Tôi đang chạy một bộ nhớ lớn gấp đôi Amazon EC2 với Windows Server 2008 AMI. Tôi đã thử nghịch với tệp my.ini để sử dụng các cài đặt tốt hơn, nhưng với tất cả những gì tôi biết tôi có thể đã làm mọi thứ tồi tệ hơn. Đây là một bãi chứa của tập tin đó:

[client]
port=3306
[mysql]
default-character-set=latin1
[mysqld]
port=3306
basedir="C:/Program Files/MySQL/MySQL Server 5.5/"
datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
character-set-server=latin1
default-storage-engine=INNODB
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
max_connections=100
query_cache_size=1024M
table_cache=256
tmp_table_size=25G
thread_cache_size=8
myisam_max_sort_file_size=100G
myisam_repair_threads = 2
myisam_sort_buffer_size=10G
key_buffer_size=5000M
bulk_insert_buffer_size = 4000M
read_buffer_size=8000M
read_rnd_buffer_size=8000M
sort_buffer_size=1G
innodb_additional_mem_pool_size=26M
innodb_flush_log_at_trx_commit=2
innodb_log_buffer_size=13M
innodb_buffer_pool_size=23G
innodb_log_file_size=622M
innodb_thread_concurrency=18
innodb_file_per_table=TRUE
join_buffer_size=4G
max_heap_table_size = 10G

Vì vậy, đây chỉ là vấn đề thay đổi các cài đặt ở trên để hoạt động tốt hơn cho môi trường của tôi? Nếu vậy, tôi nên sử dụng cài đặt nào? Tôi là người duy nhất từng sử dụng ví dụ này; Tôi sử dụng nó cho dự án sở thích cá nhân của tôi liên quan đến phân tích thống kê các bộ dữ liệu lớn. Như vậy, tôi tự do để nó tiêu thụ tất cả các tài nguyên có sẵn cho các truy vấn của riêng tôi.

Nếu đây không phải là vấn đề thay đổi các cài đặt đó, thì vấn đề là gì? Cảm ơn bất kỳ trợ giúp nào bạn có thể cung cấp cho cách cấu hình tốt hơn mọi thứ.


Bất cứ ai sử dụng bộ nhớ cache truy vấn 1g đều không biết họ đang làm gì.

@winmutt Bạn rất có thể đúng, nhưng nhận xét của bạn không giúp được ai mà không cần giải thích thêm. Bạn có thể vui lòng giúp chúng tôi bằng cách đưa ra lý do cho tình cảm của bạn?
Michael McGowan

Một công cụ hữu ích để bắt đầu là tools.percona.com/wizard
KCD

Câu trả lời:


9

Vì đây là bản cài đặt Windows, @DTest vẫn cung cấp hướng thích hợp ban đầu.

Áp dụng công thức sau:

Hầu hết mọi người sử dụng điều này:

Maximum MySQL Memory Usage = innodb_buffer_pool_size + key_buffer_size + (read_buffer_size + sort_buffer_size) X max_connections

Tôi thích điều này:

Maximum MySQL Memory Usage = innodb_buffer_pool_size + key_buffer_size + ((read_buffer_size + read_rnd_buffer_size + sort_buffer_size + join_buffer_size) X max_connections)

Các biến này là những biến bạn cần điều chỉnh cho đến khi công thức mang lại 80% RAM được cài đặt hoặc ít hơn.

sort_buffer_size
read_buffer_size
read_rnd_buffer_size
join_buffer_size
max_connections

4

Tôi sẽ thử giảm kích thước bộ đệm của bạn. Làm cho chúng lớn như bạn có chúng sẽ gây ra vấn đề. Bạn có bao nhiêu bộ nhớ để chạy các giá trị này:

query_cache_size=1024M
myisam_max_sort_file_size=100G
myisam_sort_buffer_size=10G
key_buffer_size=5000M
bulk_insert_buffer_size = 4000M
read_buffer_size=8000M
read_rnd_buffer_size=8000M
sort_buffer_size=1G
innodb_buffer_pool_size=23G

Một số kích thước bộ đệm được phân bổ cho mỗi luồng, ví dụ myisam_sort_buffer_size của 10G phân bổ 10G cho mỗi luồng.

Trước tiên tôi sẽ giảm đáng kể các giá trị đó và sau đó điều tra những giá trị nào bạn thực sự cần để có nhiều RAM được phân bổ (nếu có).


4

Một cách nhanh chóng để xác định bộ nhớ mà MySQL nghĩ nó có thể phân bổ là bao nhiêu như sau:

wget mysqltuner.pl

perl mysqltuner.pl

Khi bạn chạy tập lệnh này, nó sẽ cho bạn biết bao nhiêu phần trăm RAM được cài đặt mà MySQL nghĩ rằng nó có thể phân bổ một cách an toàn. Nếu câu trả lời được đưa ra là hơn 100%, bạn chắc chắn cần phải giảm kích thước bộ đệm của mình. Cái chính cần tập trung vào là:

sort_buffer_size read_buffer_size
read_rnd_buffer_size
tham
gia_buffer_size
max_connections
key_buffer_size (không thực sự hiệu quả qua 4G)

@DTest đã đặt hướng cho bạn trong câu trả lời của anh ấy, vì vậy +1 cho anwser của anh ấy. Kịch bản perl sẽ cho bạn biết điều gì xảy ra nếu bạn không đặt nó hoặc nếu bạn thay đổi bất kỳ giá trị nào. Đây là một ví dụ:

Một khách hàng của tôi có
read_buffer_size = 128K
read_rnd_buffer_size = 256K
sort_buffer_size = 2M
jo_buffer_size = 128K
max_connections = 1050

Đây là đầu ra từ mysqltuner.pl:

MySQLTuner 1.2.0 -
Báo cáo lỗi chính của Hayden , yêu cầu tính năng và tải xuống tại http://mysqltuner.com/
Chạy với '--help' để có thêm tùy chọn và lọc đầu ra
Vui lòng nhập thông tin đăng nhập quản trị MySQL của bạn: lwdba
Vui lòng nhập quản trị MySQL của bạn mật khẩu:

-------- Thống kê chung ---------------------------------------- ----------
[-] Kiểm tra phiên bản bỏ qua cho tập lệnh MySQLTuner
[OK] Hiện đang chạy phiên bản MySQL được hỗ trợ 5.0.51a-log-log
[!!] Chuyển sang HĐH 64 bit - Hiện tại MySQL không thể sử dụng tất cả RAM của bạn

-------- Thống kê công cụ lưu trữ --------------------------------------- ----
[-] Trạng thái: + Lưu trữ -BDB + Liên kết + InnoDB -ISAM -NDBCluster
[-] Dữ liệu trong các bảng MyISAM: 319M (Bảng: 108)
[-] Dữ liệu trong các bảng InnoDB: 2M (Bảng: 5)
[!!] Tổng số bảng phân mảnh: 22

-------- Số liệu hiệu suất ---------------------------------------- ---------
[-] Up for: 52d 23h 15m 57s (72M q [15.875 qps], 241K Conn, TX: 2B, RX: 1B)
[-] Đọc / Viết: 59% / 41%
[-] Tổng bộ đệm: 34.0M toàn cầu + 2.7M mỗi luồng (1050 luồng tối đa)
[!!] Phân bổ> RAM 2GB trên hệ thống 32 bit có thể gây mất ổn định hệ thống
[!!] Sử dụng bộ nhớ tối đa có thể: 2.8G (72% RAM đã cài đặt)
[OK] Truy vấn chậm: 0% (54 / 72M)
[OK] Sử dụng cao nhất các kết nối khả dụng: 6% (65/1050)
[OK] Kích thước bộ đệm chính / tổng chỉ số MyISAM: 8.0M / 82.1M
[OK] Tốc độ nhấn bộ đệm chính: 100.0% (4B được lưu trong bộ nhớ cache / 1M đọc)
[!!] Bộ đệm truy vấn bị vô hiệu hóa
[OK] Sắp xếp yêu cầu các bảng tạm thời: 0% (0 loại tạm thời / 948K loại)
[OK] Các bảng tạm thời được tạo trên đĩa: 3% (11K trên đĩa / tổng 380K)
[!!] Bộ đệm của luồng bị vô hiệu hóa
[!!] Tốc độ nhấn bộ đệm của bảng: 0% (64 mở / 32K mở)
[OK] Mở tệp giới hạn sử dụng: 2% (125 / 5K)
[OK] Khóa bảng thu được ngay lập tức: 99% (30M ngay lập tức / 30M khóa)
[OK] Kích thước dữ liệu / vùng đệm của dữ liệu InnoDB: 2.7M / 8.0M

-------- Khuyến nghị ----------------------------------------- ------------
khuyến nghị chung:
Chạy TỐI ƯU HÓA TABLE để bàn defragment cho hiệu suất tốt hơn
Kích hoạt tính năng đăng nhập truy vấn chậm chạp trong việc khắc phục sự cố xấu truy vấn
Set thread_cache_size đến 4 như một giá trị bắt đầu
Tăng table_cache dần để tránh giới hạn mô tả tập tin
biến để điều chỉnh:
query_cache_size (> = 8M)
thread_cache_size (bắt đầu từ 4)
table_cache (> 64)

Vui lòng lưu ý theo số liệu hiệu suất

[-] Tổng số bộ đệm: 34,0M toàn cầu + 2,7M mỗi luồng (1050 chủ đề tối đa)

rằng MySQL có thể phân bổ tới 72% RAM được cài đặt dựa trên các cài đặt trong /etc/my.cnf.

34M dựa trên innodb_buffer_pool_size và key_buffer_size kết hợp

2,7M cho mỗi luồng được dựa trên read_buffer_size + read_rnd_buffer_size + sort_buffer_size + jo_buffer_size.

Bội số của 2,7M dựa trên max_connections.

Do đó, bạn phải tăng gấp đôi các tham số này cho đến khi báo cáo số liệu Hiệu suất cho biết bạn có dưới 100% (tốt nhất là dưới 80%) RAM được cài đặt.


Tôi không chắc tôi có thể sử dụng công cụ của bạn; Tôi đang sử dụng Windows. Các tài liệu đề cập rằng Windows không được hỗ trợ, nhưng dù sao tôi cũng đã thử. Khi tôi thử chạy nó, nó chỉ ra rằng nó không thể tìm thấy mysqladmin trong $ PATH của tôi, nhưng thư mục bin của MySQL thực sự nằm trong $ PATH của tôi.
Michael McGowan

Xin lỗi, tôi đã không chú ý đến datadir Windows. Tôi sẽ thêm một câu trả lời khác.
RolandoMySQLDBA

1

Bạn không nói bạn có bao nhiêu RAM? Tôi giả sử nó có ít nhất 32GB.

innodb_buffer_pool_size - 23G

Tốt cho nhiều RAM.

truy vấn_cache_size = 1G

Nhiều quá lớn. Nó không hiệu quả khi nó lớn. Đề nghị không quá 50M.

key-buffer_size = 5G

Có thể có giới hạn cứng 4G (vẫn) trên Windows, có giới hạn cứng là 4G. 5G của bạn có thể đã biến thành 1G. Dù sao, nếu tất cả các bảng của bạn là InnoDB, tại sao lại lãng phí ram. Đặt nó thành 50M.

Vì thông báo lỗi có chính xác 1G, nên nó có mùi sort_buffer_size. 32M có thể là hợp lý.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.