Rsync ทริกเกอร์ Linux OOM killer บนไฟล์ 50 GB ไฟล์เดียว


66

ฉันมีไฟล์ 50 GB ไฟล์เดียวบน server_A และฉันกำลังคัดลอกไปยัง server_B ฉันวิ่ง

server_A$ rsync --partial --progress --inplace --append-verify 50GB_file root@server_B:50GB_file

Server_B มี RAM 32 GB พร้อมการสลับ 2 GB ส่วนใหญ่จะไม่ได้ใช้งานและควรมี RAM ฟรีจำนวนมาก มันมีพื้นที่ดิสก์มากมาย ที่ประมาณ 32 GB การถ่ายโอนยกเลิกเนื่องจากด้านระยะไกลปิดการเชื่อมต่อ

Server_B หลุดจากเครือข่ายแล้ว เราขอให้ศูนย์ข้อมูลรีบูต เมื่อฉันดูบันทึกของเคอร์เนลจากก่อนที่จะเกิดข้อผิดพลาดฉันเห็นว่ามันใช้การสลับ 0 ไบต์และรายการกระบวนการใช้หน่วยความจำน้อยมาก (กระบวนการ rsync ถูกระบุว่าใช้ RAM ขนาด 600 KB) แต่ oom_killer เป็น ก้าวต่อไปและสิ่งสุดท้ายในบันทึกคือที่ที่มันฆ่ากระบวนการเคอร์เนลของ metalog

นี่คือเคอร์เนล 3.2.59, 32 บิต (ดังนั้นจึงไม่มีกระบวนการใดสามารถแมปเกิน 4 GB ต่อไปได้)

เกือบจะเหมือนกับว่า Linux ให้ความสำคัญกับการแคชมากกว่า daemons ที่ใช้งานมานาน สิ่งที่ช่วยให้?? และฉันจะหยุดมันไม่ให้เกิดขึ้นอีกครั้งได้อย่างไร?

นี่คือผลลัพธ์ของ oom_killer:

Sep 23 02:04:16 [kernel] [1772321.850644] clamd invoked oom-killer: gfp_mask=0x84d0, order=0, oom_adj=0, oom_score_adj=0
Sep 23 02:04:16 [kernel] [1772321.850649] Pid: 21832, comm: clamd Tainted: G         C   3.2.59 #21
Sep 23 02:04:16 [kernel] [1772321.850651] Call Trace:
Sep 23 02:04:16 [kernel] [1772321.850659]  [<c01739ac>] ? dump_header+0x4d/0x160
Sep 23 02:04:16 [kernel] [1772321.850662]  [<c0173bf3>] ? oom_kill_process+0x2e/0x20e
Sep 23 02:04:16 [kernel] [1772321.850665]  [<c0173ff8>] ? out_of_memory+0x225/0x283
Sep 23 02:04:16 [kernel] [1772321.850668]  [<c0176438>] ? __alloc_pages_nodemask+0x446/0x4f4
Sep 23 02:04:16 [kernel] [1772321.850672]  [<c0126525>] ? pte_alloc_one+0x14/0x2f
Sep 23 02:04:16 [kernel] [1772321.850675]  [<c0185578>] ? __pte_alloc+0x16/0xc0
Sep 23 02:04:16 [kernel] [1772321.850678]  [<c0189e74>] ? vma_merge+0x18d/0x1cc
Sep 23 02:04:16 [kernel] [1772321.850681]  [<c01856fa>] ? handle_mm_fault+0xd8/0x15d
Sep 23 02:04:16 [kernel] [1772321.850685]  [<c012305a>] ? do_page_fault+0x20e/0x361
Sep 23 02:04:16 [kernel] [1772321.850688]  [<c018a9c4>] ? sys_mmap_pgoff+0xa2/0xc9
Sep 23 02:04:16 [kernel] [1772321.850690]  [<c0122e4c>] ? vmalloc_fault+0x237/0x237
Sep 23 02:04:16 [kernel] [1772321.850694]  [<c08ba7e6>] ? error_code+0x5a/0x60
Sep 23 02:04:16 [kernel] [1772321.850697]  [<c08b0000>] ? cpuid4_cache_lookup_regs+0x372/0x3b2
Sep 23 02:04:16 [kernel] [1772321.850700]  [<c0122e4c>] ? vmalloc_fault+0x237/0x237
Sep 23 02:04:16 [kernel] [1772321.850701] Mem-Info:
Sep 23 02:04:16 [kernel] [1772321.850703] DMA per-cpu:
Sep 23 02:04:16 [kernel] [1772321.850704] CPU    0: hi:    0, btch:   1 usd:   0
Sep 23 02:04:16 [kernel] [1772321.850706] CPU    1: hi:    0, btch:   1 usd:   0
Sep 23 02:04:16 [kernel] [1772321.850707] CPU    2: hi:    0, btch:   1 usd:   0
Sep 23 02:04:16 [kernel] [1772321.850709] CPU    3: hi:    0, btch:   1 usd:   0
Sep 23 02:04:16 [kernel] [1772321.850711] CPU    4: hi:    0, btch:   1 usd:   0
Sep 23 02:04:16 [kernel] [1772321.850713] CPU    5: hi:    0, btch:   1 usd:   0
Sep 23 02:04:16 [kernel] [1772321.850714] CPU    6: hi:    0, btch:   1 usd:   0
Sep 23 02:04:16 [kernel] [1772321.850716] CPU    7: hi:    0, btch:   1 usd:   0
Sep 23 02:04:16 [kernel] [1772321.850718] Normal per-cpu:
Sep 23 02:04:16 [kernel] [1772321.850719] CPU    0: hi:  186, btch:  31 usd:  70
Sep 23 02:04:16 [kernel] [1772321.850721] CPU    1: hi:  186, btch:  31 usd: 116
Sep 23 02:04:16 [kernel] [1772321.850723] CPU    2: hi:  186, btch:  31 usd: 131
Sep 23 02:04:16 [kernel] [1772321.850724] CPU    3: hi:  186, btch:  31 usd:  76
Sep 23 02:04:16 [kernel] [1772321.850726] CPU    4: hi:  186, btch:  31 usd:  29
Sep 23 02:04:16 [kernel] [1772321.850728] CPU    5: hi:  186, btch:  31 usd:  61
Sep 23 02:04:16 [kernel] [1772321.850731] CPU    7: hi:  186, btch:  31 usd:  17
Sep 23 02:04:16 [kernel] [1772321.850733] HighMem per-cpu:
Sep 23 02:04:16 [kernel] [1772321.850734] CPU    0: hi:  186, btch:  31 usd:   2
Sep 23 02:04:16 [kernel] [1772321.850736] CPU    1: hi:  186, btch:  31 usd:  69
Sep 23 02:04:16 [kernel] [1772321.850738] CPU    2: hi:  186, btch:  31 usd:  25
Sep 23 02:04:16 [kernel] [1772321.850739] CPU    3: hi:  186, btch:  31 usd:  27
Sep 23 02:04:16 [kernel] [1772321.850741] CPU    4: hi:  186, btch:  31 usd:   7
Sep 23 02:04:16 [kernel] [1772321.850743] CPU    5: hi:  186, btch:  31 usd: 188
Sep 23 02:04:16 [kernel] [1772321.850744] CPU    6: hi:  186, btch:  31 usd:  25
Sep 23 02:04:16 [kernel] [1772321.850746] CPU    7: hi:  186, btch:  31 usd: 158
Sep 23 02:04:16 [kernel] [1772321.850750] active_anon:117913 inactive_anon:9942 isolated_anon:0
Sep 23 02:04:16 [kernel] [1772321.850751]  active_file:106466 inactive_file:7784521 isolated_file:0
Sep 23 02:04:16 [kernel] [1772321.850752]  unevictable:40 dirty:0 writeback:61 unstable:0
Sep 23 02:04:16 [kernel] [1772321.850753]  free:143494 slab_reclaimable:128312 slab_unreclaimable:4089
Sep 23 02:04:16 [kernel] [1772321.850754]  mapped:6706 shmem:308 pagetables:915 bounce:0
Sep 23 02:04:16 [kernel] [1772321.850759] DMA free:3624kB min:140kB low:172kB high:208kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolate
d(file):0kB present:15808kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:240kB slab_unreclaimable:0kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB writeback_tm
p:0kB pages_scanned:0 all_unreclaimable? yes
Sep 23 02:04:16 [kernel] [1772321.850763] lowmem_reserve[]: 0 869 32487 32487
Sep 23 02:04:16 [kernel] [1772321.850770] Normal free:8056kB min:8048kB low:10060kB high:12072kB active_anon:0kB inactive_anon:0kB active_file:248kB inactive_file:388kB unevictable:0kB isolated(anon)
:0kB isolated(file):0kB present:890008kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:513008kB slab_unreclaimable:16356kB kernel_stack:1888kB pagetables:3660kB unstable:0
kB bounce:0kB writeback_tmp:0kB pages_scanned:1015 all_unreclaimable? yes
Sep 23 02:04:16 [kernel] [1772321.850774] lowmem_reserve[]: 0 0 252949 252949
Sep 23 02:04:16 [kernel] [1772321.850785] lowmem_reserve[]: 0 0 0 0
Sep 23 02:04:16 [kernel] [1772321.850788] DMA: 0*4kB 7*8kB 3*16kB 6*32kB 4*64kB 6*128kB 5*256kB 2*512kB 0*1024kB 0*2048kB 0*4096kB = 3624kB
Sep 23 02:04:16 [kernel] [1772321.850795] Normal: 830*4kB 80*8kB 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 1*4096kB = 8056kB
Sep 23 02:04:16 [kernel] [1772321.850802] HighMem: 13*4kB 14*8kB 2*16kB 2*32kB 0*64kB 0*128kB 2*256kB 2*512kB 3*1024kB 0*2048kB 136*4096kB = 561924kB
Sep 23 02:04:16 [kernel] [1772321.850809] 7891360 total pagecache pages
Sep 23 02:04:16 [kernel] [1772321.850811] 0 pages in swap cache
Sep 23 02:04:16 [kernel] [1772321.850812] Swap cache stats: add 0, delete 0, find 0/0
Sep 23 02:04:16 [kernel] [1772321.850814] Free swap  = 1959892kB
Sep 23 02:04:16 [kernel] [1772321.850815] Total swap = 1959892kB
Sep 23 02:04:16 [kernel] [1772321.949081] 8650736 pages RAM
Sep 23 02:04:16 [kernel] [1772321.949084] 8422402 pages HighMem
Sep 23 02:04:16 [kernel] [1772321.949085] 349626 pages reserved
Sep 23 02:04:16 [kernel] [1772321.949086] 7885006 pages shared
Sep 23 02:04:16 [kernel] [1772321.949087] 316864 pages non-shared
Sep 23 02:04:16 [kernel] [1772321.949089] [ pid ]   uid  tgid total_vm      rss cpu oom_adj oom_score_adj name
            (rest of process list omitted)
Sep 23 02:04:16 [kernel] [1772321.949656] [14579]     0 14579      579      171   5       0             0 rsync
Sep 23 02:04:16 [kernel] [1772321.949662] [14580]     0 14580      677      215   5       0             0 rsync
Sep 23 02:04:16 [kernel] [1772321.949669] [21832]   113 21832    42469    37403   0       0             0 clamd
Sep 23 02:04:16 [kernel] [1772321.949674] Out of memory: Kill process 21832 (clamd) score 4 or sacrifice child
Sep 23 02:04:16 [kernel] [1772321.949679] Killed process 21832 (clamd) total-vm:169876kB, anon-rss:146900kB, file-rss:2712kB

นี่คือเอาต์พุต 'top' หลังจากทำซ้ำคำสั่ง rsync ของฉันในฐานะผู้ใช้ที่ไม่ใช่รูท:

top - 03:05:55 up  8:43,  2 users,  load average: 0.04, 0.08, 0.09
Tasks: 224 total,   1 running, 223 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0% us,  0.0% sy,  0.0% ni, 99.9% id,  0.0% wa,  0.0% hi,  0.0% si
Mem:  33204440k total, 32688600k used,   515840k free,   108124k buffers
Swap:  1959892k total,        0k used,  1959892k free, 31648080k cached

นี่คือพารามิเตอร์ sysctl vm:

# sysctl -a | grep '^vm'
vm.overcommit_memory = 0
vm.panic_on_oom = 0
vm.oom_kill_allocating_task = 0
vm.oom_dump_tasks = 1
vm.overcommit_ratio = 50
vm.page-cluster = 3
vm.dirty_background_ratio = 1
vm.dirty_background_bytes = 0
vm.dirty_ratio = 0
vm.dirty_bytes = 15728640
vm.dirty_writeback_centisecs = 500
vm.dirty_expire_centisecs = 3000
vm.nr_pdflush_threads = 0
vm.swappiness = 60
vm.lowmem_reserve_ratio = 256   32      32
vm.drop_caches = 0
vm.min_free_kbytes = 8192
vm.percpu_pagelist_fraction = 0
vm.max_map_count = 65530
vm.laptop_mode = 0
vm.block_dump = 0
vm.vfs_cache_pressure = 100
vm.legacy_va_layout = 0
vm.stat_interval = 1
vm.mmap_min_addr = 4096
vm.vdso_enabled = 2
vm.highmem_is_dirtyable = 0
vm.scan_unevictable_pages = 0

2
ฉันไม่มีความเชี่ยวชาญในการอ่านข้อความข้อผิดพลาดของเคอร์เนล แต่ฉันไม่เห็นสิ่งบ่งชี้ว่า B กำลังใช้งานคอร์ขนาด 32GB ก่อนที่เราจะดำเนินการตามสมมติฐานต่อไปคุณสามารถยืนยันได้หรือไม่ว่าเป็นปัจจุบัน เนื่องจากมีความแตกต่างอย่างมากระหว่างหน่วยความจำที่ใช้งานกล่องหลัก 32GB แต่ก็มีเพียง 4GB เท่านั้น
MadHatter

อัปเดตด้วยเอาต์พุตสูงสุด นี่คือหลังจากรันคำสั่ง rsync เดียวกันกับผู้ใช้ที่ไม่ใช่รูท ค่อนข้างมาก แต่ 1GB ใช้สำหรับแคชทันที
dataless

ขอบคุณ อย่างที่ฉันพูดฉันไม่มีความเชี่ยวชาญ - แต่ดูเหมือนว่าควรค่าแก่การตรวจสอบ
MadHatter

คุณควรตรวจสอบด้วยว่าเคอร์เนลของคุณอนุญาตให้ทำการสลับ (เช่นการสลับไม่ได้ถูกปิด) (และคุณควรจะทุ่มเทพื้นที่ดิสก์ที่ใหญ่ขึ้นสมมติว่า 16Gb หรือแม้กระทั่ง 32Gb) บางคนที่แปลก ๆ ในเน็ตแนะนำให้ปิดการแลกเปลี่ยนซึ่งผิดปกติมาก
Olivier Dulac

@OlivierDulac คุณหมายถึงการตั้งค่าใด คอมไพล์การสนับสนุนถูกคอมไพล์หรือเราจะไม่สามารถเมานท์สแวร์ได้และ 'swappiness' ถูกตั้งค่าเป็น 60 สำหรับขนาดสว็อปนั้นจะไม่ทำให้ปัญหาแย่ลงในเคอร์เนลแบบ 32 บิตใช่ไหม คำตอบปรากฏว่าโครงสร้างข้อมูลเคอร์เนลเป็นสิ่งที่ทำลายเรา เราไม่ได้ใช้กระบวนการผู้ใช้ 32GB เราแค่ต้องการหน่วยความจำแคชของดิสก์เพื่อประสิทธิภาพ
dataless

คำตอบ:


178

ดังนั้นให้เราอ่านผลลัพธ์ของนักฆ่าและดูว่าสามารถเรียนรู้อะไรได้บ้าง

เมื่อทำการวิเคราะห์บันทึกของนักฆ่า OOM มันเป็นสิ่งสำคัญที่จะต้องดูว่าอะไรเป็นสาเหตุ บรรทัดแรกของบันทึกของคุณทำให้เราทราบเบาะแส:

[เคอร์เนล] [1772321.850644] clamd เรียกใช้ oom-killer: gfp_mask = 0x84d0, คำสั่ง = 0

order=0กำลังบอกเราว่ามีการร้องขอหน่วยความจำเท่าใด การจัดการหน่วยความจำของเคอร์เนลสามารถจัดการหมายเลขหน้าในพาวเวอร์ 2 เท่านั้นดังนั้น clamd ได้ขอหน่วยความจำ2 0หน้าหรือ 4KB

GFP_MASK สองบิตที่ต่ำที่สุด (รับมาสก์หน้าฟรี) ประกอบด้วยมาสก์โซนที่ เรียกว่าบอกตัวจัดสรรซึ่งโซนที่จะรับหน่วยความจำจาก :

Flag            value      Description
                0x00u      0 implicitly means allocate from ZONE_NORMAL
__GFP_DMA       0x01u      Allocate from ZONE_DMA if possible
__GFP_HIGHMEM   0x02u      Allocate from ZONE_HIGHMEM if possible

โซนหน่วยความจำเป็นแนวคิดที่สร้างขึ้นส่วนใหญ่ด้วยเหตุผลความเข้ากันได้ ในมุมมองที่เรียบง่ายมีสามโซนสำหรับเคอร์เนล x86:

Memory range   Zone       Purpose 

0-16 MB        DMA        Hardware compatibility (devices)
16 - 896 MB    NORMAL     space directly addressable by the Kernel, userland 
> 896 MB       HIGHMEM    userland, space addressable by the Kernel via kmap() calls

ในกรณีของคุณ zonemask เป็น 0 หมาย clamd ZONE_NORMALร้องขอจากหน่วยความจำ

ธงอื่น ๆ กำลังแก้ไข

/*
 * Action modifiers - doesn't change the zoning
 *
 * __GFP_REPEAT: Try hard to allocate the memory, but the allocation attempt
 * _might_ fail.  This depends upon the particular VM implementation.
 *
 * __GFP_NOFAIL: The VM implementation _must_ retry infinitely: the caller
 * cannot handle allocation failures.
 *
 * __GFP_NORETRY: The VM implementation must not retry indefinitely.
 */
#define __GFP_WAIT      0x10u   /* Can wait and reschedule? */
#define __GFP_HIGH      0x20u   /* Should access emergency pools? */
#define __GFP_IO        0x40u   /* Can start physical IO? */
#define __GFP_FS        0x80u   /* Can call down to low-level FS? */
#define __GFP_COLD      0x100u  /* Cache-cold page required */
#define __GFP_NOWARN    0x200u  /* Suppress page allocation failure warning */
#define __GFP_REPEAT    0x400u  /* Retry the allocation.  Might fail */
#define __GFP_NOFAIL    0x800u  /* Retry for ever.  Cannot fail */
#define __GFP_NORETRY   0x1000u /* Do not retry.  Might fail */
#define __GFP_NO_GROW   0x2000u /* Slab internal usage */
#define __GFP_COMP      0x4000u /* Add compound page metadata */
#define __GFP_ZERO      0x8000u /* Return zeroed page on success */
#define __GFP_NOMEMALLOC 0x10000u /* Don't use emergency reserves */
#define __GFP_NORECLAIM  0x20000u /* No realy zone reclaim during allocation */

ตามเอกสารลินุกซ์ MMดังนั้น requst ของคุณมีธงสำหรับGFP_ZERO, GFP_REPEAT, GFP_FS, GFP_IOและGFP_WAITจึงเป็นไม่จู้จี้จุกจิกโดยเฉพาะอย่างยิ่ง

ดังนั้นสิ่งที่เกิดขึ้นด้วยZONE_NORMAL? สามารถดูสถิติทั่วไปบางอย่างเพิ่มเติมในผลลัพธ์ OOM:

[เคอร์เนล] [1772321.850770] ปกติฟรี: 8056kB ต่ำสุด: 8048kB ต่ำ: 10060kBสูง: 12072kB ไฟล์ active_anon: 0kB inactive_anon: 0kB active_file: 248kB ไม่ใช้งานไฟล์: 388kB ไม่สามารถใช้งานได้: 0kB ไม่ใช้งาน: 0kB

เห็นได้ชัดว่านี่คือfreeเป็นเพียง 8K จากและวิธีการภายใต้min lowซึ่งหมายความว่าตัวจัดการหน่วยความจำของโฮสต์ของคุณค่อนข้างลำบากและ kswapd ควรจะสลับหน้าออกไปแล้วเนื่องจากอยู่ในระยะสีเหลืองของกราฟด้านล่าง: กราฟผู้จัดการหน่วยความจำลินุกซ์

ข้อมูลเพิ่มเติมเกี่ยวกับการกระจายตัวของหน่วยความจำของโซนมีให้ที่นี่:

[เคอร์เนล] [1772321.850795] ปกติ: 830 * 4kB 80 * 8kB 0 * 16kB 0 * 32kB 0 * 64kB 0 * 128kB 0 * 256kB 0 * 512kB 0 * 1024kB 0 * 2048kB 1 * 4096kB = 8056kB

โดยพื้นฐานแล้วระบุว่าคุณมีหน้าเว็บที่ต่อเนื่องกันขนาด 4MB โดยที่เหลือจะแยกส่วนเป็นหน้า 4KB เป็นส่วนใหญ่

ดังนั้นขอสรุป:

  • คุณมีกระบวนการ userland ( clamd) รับหน่วยความจำZONE_NORMALในขณะที่การจัดสรรหน่วยความจำที่ไม่ได้รับสิทธิพิเศษมักจะดำเนินการจากZONE_HIMEM
  • ผู้จัดการหน่วยความจำในขั้นตอนนี้ควรจะสามารถแสดงหน้า 4K ที่ร้องขอได้แม้ว่าคุณจะดูเหมือนจะมีแรงกดดันต่อหน่วยความจำอย่างมากก็ตาม ZONE_NORMAL
  • ตามkswapdกฎของระบบควรจะเห็นกิจกรรมการเพจไว้ล่วงหน้า แต่ไม่มีอะไรถูกเปลี่ยนแม้ภายใต้ความกดดันของหน่วยความจำZONE_NORMALโดยไม่มีสาเหตุที่ชัดเจน
  • ไม่มีการข้างต้นให้เหตุผลที่ชัดเจนว่าทำไมoom-killerถูกเรียก

ทั้งหมดนี้ดูค่อนข้างแปลก แต่อย่างน้อยก็เกี่ยวข้องกับสิ่งที่อธิบายไว้ในส่วนที่ 2.5 ของหนังสือ "การทำความเข้าใจกับ Linux Virtual Memory Manager" ของ John O'Gorman ที่ยอดเยี่ยม :

เนื่องจากพื้นที่ที่อยู่ที่ใช้งานได้โดยเคอร์เนล (ZONE_NORMAL) มีขนาด จำกัด เคอร์เนลจึงรองรับแนวคิดของหน่วยความจำสูง [... ] หากต้องการเข้าถึงหน่วยความจำระหว่างช่วง 1GiB และ 4GiB เคอร์เนลจะจับคู่หน้าจากหน่วยความจำสูงไปยัง ZONE_NORMAL ด้วย kmap () ชั่วคราว [ ... ]

ซึ่งหมายความว่าในการอธิบาย 1GiB ของหน่วยความจำต้องใช้หน่วยความจำเคอร์เนลประมาณ 11MiB ดังนั้นด้วย 16GiB ใช้หน่วยความจำ 176MiB จึงสร้างความกดดันให้กับ ZONE_NORMAL สิ่งนี้ไม่ได้เลวร้ายเกินไปจนกว่าจะมีการพิจารณาโครงสร้างอื่นที่ใช้ ZONE_NORMAL แม้แต่โครงสร้างที่มีขนาดเล็กมากเช่น Page Table Entries (PTE) ต้องการประมาณ 16MiB ในกรณีที่เลวร้ายที่สุด นี้จะทำให้ 16GiB เกี่ยวกับขีด จำกัด ในทางปฏิบัติสำหรับหน่วยความจำกายภาพใช้ได้ลินุกซ์บน x86

(เน้นเป็นของฉัน)

ตั้งแต่ 3.2 มีความก้าวหน้ามากมายในการจัดการหน่วยความจำมากกว่า 2.6 นี่ไม่ใช่คำตอบที่แน่นอน แต่เป็นคำใบ้ที่แข็งแกร่งมาก ๆ ที่ฉันต้องติดตามก่อน ลดหน่วยความจำที่ใช้งานได้ของโฮสต์ให้เหลือเพียง 16G มากที่สุดโดยใช้mem=พารามิเตอร์เคอร์เนลหรือโดยการฉีกครึ่ง DIMM ออกจากเซิร์ฟเวอร์

ในท้ายที่สุดใช้เคอร์เนล 64 บิต

เพื่อนมันปี 2558


13
เมื่อฉันพูดข้างต้น " ฉันไม่มีความเชี่ยวชาญ " นี่คือสิ่งที่ฉันหวังว่าจะอ่าน +1000 ถ้าฉันทำได้ +1 แน่นอน ช่างเป็นคำตอบที่ยอดเยี่ยม!
MadHatter

18
นั่นเป็นสิ่งที่สวยงาม ยังคงมีความหวังสำหรับ SF
โรมัน

9
@ dataless ใช่ ฉันสงสัยว่า ZONE_NORMAL ทั้งหมดของคุณเต็มไปด้วยข้อมูลเมตาเกี่ยวกับพื้นที่หน่วยความจำส่วนบน เมื่อกระบวนการผู้ใช้กำลังร้องขอหน้าหน่วยความจำเป็นไปได้มากที่สุดที่จะร้องขอ ZONE_HIGHMEM (ซึ่งอาจได้รับการอัพเกรดโดย MM เป็น ZONE_NORMAL ถ้า HIGHMEM ไม่มีหน้าว่างที่จะให้บริการตามคำขอ แต่ NORMAL มี) ดังนั้นเว้นแต่ ZONE_HIGHMEM อยู่ภายใต้ความกดดันหน่วยความจำ (ของคุณไม่ใช่) ZONE_NORMAL จะไม่มีหน้ากระบวนการของผู้ใช้พื้นที่
the-wabbit

3
[ตบหมัดบนแป้นพิมพ์] มอบรางวัลนี้แก่คุณ
underscore_d

3
@ คำถามเครือข่ายที่น่าสนใจ
CodesInChaos

4

บางสิ่ง ...

กฏของหัวแม่มือสำหรับพื้นที่สว็อปของฉันต้องมี RAM อย่างน้อย 2 เท่า สิ่งนี้ทำให้ page / swap daemon สามารถ reorg หน่วยความจำได้อย่างมีประสิทธิภาพ

Server_B มี RAM 32GB ให้ลองกำหนดค่าให้เป็น 64GB ของการสลับ IMO ที่ 2GB ของพื้นที่ swap เซิร์ฟเวอร์ของคุณมีเป็นวิธีที่ต่ำเกินไปโดยเฉพาะอย่างยิ่งสำหรับเซิร์ฟเวอร์

หากคุณไม่มีพาร์ติชั่นพิเศษที่คุณสามารถสร้างเป็นพาร์ติชั่นสว็อปคุณสามารถทดสอบสิ่งนี้ได้โดยการสร้างไฟล์และติดตั้งเป็นพาร์ติชั่นสว็อป [มันจะช้า] ดูhttps://www.maketecheasier.com/swap-partitions-on-linux/

เนื่องจาก server_B มีพื้นที่ดิสก์มากมาย - ไม่จำเป็นต้องแทนที่และอาจไม่พึงประสงค์เนื่องจากอาจเป็นสาเหตุให้ rsync ใช้ 32GB - แทนที่จะมีประโยชน์จริง ๆ ถ้าคุณมีพื้นที่ว่างในระบบแฟ้ม [ที่คุณไม่ได้] หรือมีความต้องการประสิทธิภาพพิเศษบางอย่าง

ฉันเดาว่า rsync จะต้องการใช้ RAM 50GB [ขนาดไฟล์] กับตัวเลือกปัจจุบันของคุณ โดยปกติแล้ว rsync ไม่ต้องการหน่วยความจำจำนวนมากในการทำงานดังนั้นตัวเลือกอย่างน้อยหนึ่งตัวของคุณอาจเป็นปัญหา ฉันถ่ายโอนไฟล์ 200GB เป็นประจำโดยไม่มีปัญหา

ทำการทดสอบบางอย่างโดยไม่ใช้ตัวเลือก ทำสิ่งนี้กับไฟล์ที่มีขนาดเล็กกว่าเช่น 10GB - สิ่งนี้จะช่วยป้องกันเคอร์เนลที่ทำให้ตื่นตระหนก ตรวจสอบการใช้งานหน่วยความจำของ rsync

เพิ่มตัวเลือกกลับทีละหนึ่งทีละครั้งเพื่อดูว่าตัวเลือกใด [หรือการรวมกันของตัวเลือก] ทำให้ rsync เริ่ม pigging ออกจาก RAM (เช่นในขณะที่มีการถ่ายโอนเกิดขึ้นการใช้ ram ของ rsync จะเพิ่มขึ้นตามปริมาณ ฯลฯ )

หากคุณต้องการตัวเลือกที่ทำให้ rsync เก็บอิมเมจไฟล์ใน ram คุณจะต้องใช้พื้นที่ swap เพิ่มเติมและขนาดไฟล์สูงสุดของคุณจะถูก จำกัด ตามลำดับ

อีกสองสามสิ่ง [อัพเดท]:

(1) การติดตามสแต็กของเคอร์เนลแสดงให้เห็นว่า rsync เป็นเพจที่มีข้อบกพร่องในพื้นที่ mmap มันอาจเป็นไฟล์ mmaping mmap ไม่รับประกันว่ามันจะล้างข้อมูลในดิสก์จนกว่าไฟล์จะถูกปิด [ซึ่งแตกต่างจากการอ่าน / เขียน] ซึ่งไปที่แคชบล็อก FS ทันที [ซึ่งจะถูกล้างข้อมูล]

(2) เคอร์เนลเกิดความผิดพลาด / ความตื่นตระหนกเกิดขึ้นเมื่อขนาดการถ่ายโอนมีขนาดเท่ากับ RAM เห็นได้ชัดว่า rsync กำลังคว้าหน่วยความจำที่ไม่ใช่ fscache จำนวนมากผ่าน malloc หรือ mmap อีกครั้งด้วยตัวเลือกที่คุณระบุ rsync จะจัดสรรหน่วยความจำ 50GB เพื่อถ่ายโอนไฟล์ 50GB

(3) ถ่ายโอนไฟล์ 24GB นั่นอาจจะใช้ได้ จากนั้นให้บูตเคอร์เนลด้วย mem = 16G และทำการทดสอบไฟล์ 24GB อีกครั้ง มันจะระเบิดที่ 16GB มากกว่า 32GB นี่จะเป็นการยืนยันว่า rsync ต้องการหน่วยความจำจริงๆ

(4) ก่อนที่คุณจะพูดว่าการเพิ่มการแลกเปลี่ยนนั้นไร้สาระลองเพิ่ม [ผ่านวิธีการสลับไฟล์] การทำและทดสอบทำได้ง่ายกว่าข้อโต้แย้งเชิงวิชาการทั้งหมดเกี่ยวกับวิธีการแลกเปลี่ยนไม่จำเป็น แม้ว่ามันจะไม่ใช่ทางออก แต่คุณอาจเรียนรู้บางสิ่งจากมัน ฉันจะเดิมพันว่า mem = 16G ทดสอบจะประสบความสำเร็จโดยไม่ต้องตกใจ / ผิดพลาด

(5) โอกาสที่ rsync กำลังกดปุ่ม swap แต่มันเกิดขึ้นเร็วเกินไปที่จะดูด้วยอันดับสูงสุดก่อนที่ OOM จะเตะและฆ่า rsync เมื่อถึงเวลาที่ rsync ถึง 32GB กระบวนการอื่น ๆ ก็ถูกบังคับให้เปลี่ยนโดยเฉพาะอย่างยิ่งหากไม่มีการใช้งาน บางทีการรวมกันของ "ฟรี" และ "ยอดนิยม" จะให้ภาพที่ดีขึ้น

(6) หลังจาก rsync ถูกฆ่ามันต้องใช้เวลาในการล้าง mmap ให้กับ FS ไม่เร็วพอสำหรับ OOM และมันเริ่มฆ่าสิ่งอื่น ๆ (บางภารกิจมีความสำคัญอย่างยิ่ง] นั่นคือ mmap flush และ OOM กำลังแข่ง หรือ OOM มีข้อบกพร่อง มิฉะนั้นจะไม่มีข้อผิดพลาด

(7) จากประสบการณ์ของฉันเมื่อระบบ "ชนกับกำแพงหน่วยความจำ" ระบบ Linux ใช้เวลานานในการกู้คืนเต็มที่ และบางครั้งมันก็ไม่สามารถกู้คืนได้อย่างถูกต้องและวิธีเดียวที่จะเคลียร์มันคือการรีบูต ตัวอย่างเช่นฉันมี RAM 12GB เมื่อฉันรันงานที่ใช้หน่วยความจำ 40GB [ฉันมี 120GB ของการสลับเพื่อรองรับงานที่มีขนาดใหญ่] และจากนั้นฆ่ามันใช้เวลาประมาณ 10 นาทีเพื่อให้ระบบกลับสู่การตอบสนองปกติ [พร้อมไฟดิสก์แข็งตลอดเวลา] .

(8) เรียกใช้ rsync โดยไม่มีตัวเลือก สิ่งนี้จะได้ผล รับตัวอย่างพื้นฐานในการทำงานจาก จากนั้นเพิ่มกลับ - แทนที่และทดสอบซ้ำ จากนั้นทำ - ผนวกตรวจสอบแทน จากนั้นลองทั้งสองอย่าง ค้นหาว่าตัวเลือกใดที่จะทำให้ rsync ทำงานอย่างมหาศาล จากนั้นตัดสินใจว่าคุณจะอยู่ได้โดยปราศจากมัน ถ้า - ในที่นี้เป็นผู้กระทำผิดนั่นเป็นเรื่องไร้สาระเนื่องจากคุณมีพื้นที่ดิสก์เหลือเฟือ หากคุณต้องมีตัวเลือกคุณจะต้องได้รับพื้นที่สว็อปเพื่อรองรับ malloc / mmap ที่ rsync จะทำ

ปรับปรุงที่สอง:

กรุณาทำการทดสอบ mem = และไฟล์ที่เล็กกว่าจากด้านบน

คำถามกลาง: ทำไม rsync ถึงถูกสังหารโดย OOM? ใครคือความทรงจำในการเคี้ยว?

ฉันอ่าน [แต่ลืม] เกี่ยวกับระบบที่เป็น 32 บิต ดังนั้นฉันยอมรับ rsync อาจไม่รับผิดชอบโดยตรง (ผ่าน malloc / mmap - glibc ใช้ malloc ขนาดใหญ่ผ่านทาง mmaps แบบไม่ระบุชื่อ / ส่วนตัว) และความผิดพลาดหน้า mmap ของ rsync เพียงเรียก OOM โดยบังเอิญ จากนั้น OOM จะคำนวณหน่วยความจำทั้งหมดที่ใช้โดย rsync ทั้งทางตรงและทางอ้อม [แคช FS, ซ็อกเก็ตบัฟเฟอร์ ฯลฯ ] และตัดสินใจว่ามันเป็นตัวเลือกอันดับต้น ๆ ดังนั้นการตรวจสอบการใช้งานหน่วยความจำทั้งหมดอาจเป็นประโยชน์ ฉันสงสัยว่ามันจะคืบคลานขึ้นในอัตราเดียวกับการถ่ายโอนไฟล์ เห็นได้ชัดว่ามันไม่ควร

บางสิ่งที่คุณสามารถตรวจสอบใน / proc หรือ / proc / rsync_pid ผ่านสคริปต์ perl หรือ python ในการวนรอบอย่างรวดเร็ว [สคริปต์ทุบตีอาจจะไม่เร็วพอสำหรับเหตุการณ์สิ้นสุดของโลก] ที่สามารถตรวจสอบทั้งหมดของ หลายร้อยครั้ง / วินาทีต่อไปนี้ คุณสามารถเรียกใช้สิ่งนี้ได้ในลำดับความสำคัญสูงกว่า rsync ดังนั้นมันจะเก็บไว้ใน RAM และทำงานเพื่อให้คุณสามารถตรวจสอบสิ่งต่าง ๆ ก่อนที่จะเกิดข้อผิดพลาดและหวังว่าในช่วง OOM เพื่อให้คุณเห็นว่าทำไม OOM ถึงคลั่ง:

/ proc / meminfo - เพื่อรับเกรนละเอียดมากขึ้นเกี่ยวกับการใช้ swap ที่ "point of impact" ที่จริงแล้วการได้รับหมายเลขสุดท้ายว่าจำนวน RAM ที่ใช้ทั้งหมดอาจมีประโยชน์มากกว่า แม้ว่าด้านบนจะให้สิ่งนี้มันอาจไม่เร็วพอที่จะแสดงสถานะของเอกภพก่อน "บิ๊กแบง" (เช่น 10 มิลลิวินาทีสุดท้าย)

ไดเร็กทอรี / proc / rsync_pid / fd การอ่าน symlinks จะช่วยให้คุณระบุว่า fd ใดที่เปิดอยู่ในไฟล์เป้าหมาย (เช่น readlink ของ / proc / rsync_pid / fd / 5 -> target_file) อาจต้องดำเนินการเพียงครั้งเดียวเพื่อรับหมายเลข fd [ควรคงที่]

เมื่อทราบหมายเลข fd ให้ดูที่ / proc / rsync_pid / fdinfo / fd มันเป็นไฟล์ข้อความที่ดูเหมือนว่า:

pos: <file_position>
ธง: blah_blah
mnt_id: blah_blah

การตรวจสอบค่า "pos" อาจมีประโยชน์เนื่องจาก "ตำแหน่งไฟล์สุดท้าย" อาจมีประโยชน์ หากคุณทำการทดสอบหลายอย่างด้วยขนาดและตัวเลือก mem = ที่แตกต่างกันตำแหน่งไฟล์สุดท้ายจะติดตามสิ่งเหล่านี้ [และอย่างไร] ผู้ต้องสงสัยปกติ: ตำแหน่งไฟล์ == RAM ที่มีอยู่

แต่วิธีที่ง่ายที่สุดคือเริ่มต้นด้วย "เซิร์ฟเวอร์ rsync local_file: remote_file" และตรวจสอบว่าใช้งานได้ คุณอาจได้ผลลัพธ์ที่คล้ายกัน [แต่เร็วกว่า] โดยทำ "ssh เซิร์ฟเวอร์ rsync file_a file_b" [คุณต้องสร้าง 50GB file_a ก่อน] วิธีง่ายๆในการสร้าง file_a คือ scp local_system: original_file server: file_a และสิ่งนี้อาจน่าสนใจสำหรับตัวเอง (เช่นทำงานเมื่อ rsync ล่มหรือไม่ถ้า scp ทำงาน แต่ rsync ล้มเหลวชี้ไปที่ rsync หาก scp ล้มเหลวประเด็นนี้ กับสิ่งอื่นเช่นไดรเวอร์ NIC) การทำ ssh rsync ยังนำ NIC ออกจากสมการซึ่งอาจเป็นประโยชน์ หากนั่นทำให้ระบบล้มเหลวแสดงว่ามีบางอย่างผิดปกติ หากประสบความสำเร็จ [ตามที่ฉันพูดถึง] ให้เริ่มเพิ่มตัวเลือกแบบหนึ่งต่อหนึ่ง

ฉันเกลียดที่จะปฏิเสธประเด็นนี้ แต่การเพิ่ม swap บางอย่างผ่าน swap-to-file อาจเปลี่ยน / ชะลอพฤติกรรมการขัดข้องและอาจมีประโยชน์ในฐานะเครื่องมือวินิจฉัย หากเพิ่มให้พูดถึง 16GB ของการสลับการหน่วงเวลาการทำงานผิดพลาด [ตามที่วัดได้จากการใช้หน่วยความจำหรือตำแหน่งไฟล์เป้าหมาย] จาก 32GB เป็น 46GB แล้วนั่นจะเป็นการพูดอะไรบางอย่าง

อาจไม่เป็นกระบวนการเฉพาะใด ๆ แต่เป็นไดรเวอร์เคอร์เนลที่ผิดพลาดที่กำลังเคี้ยวหน่วยความจำ เคอร์เนลภายใน vmalloc จัดสรรข้อมูลและสามารถสลับออกได้ IIRC มันไม่ได้ผูกพันตามที่อยู่ภายใต้สถานการณ์ทั้งหมด

เห็นได้ชัดว่า OOM กำลังสับสน / ตื่นตระหนก นั่นคือมันฆ่า rsync แต่ไม่เห็นหน่วยความจำที่เป็นอิสระในเวลาที่เหมาะสมและไปหาเหยื่อรายอื่น บางคนอาจมีความสำคัญต่อการทำงานของระบบ

กัน malloc / mmap สิ่งนี้อาจเกิดจากแคช FS ที่ไม่ได้ฟลัชซึ่งใช้เวลานาน (เช่นกับข้อมูลที่ไม่ได้ล้าง 30GB โดยสมมติว่าอัตราดิสก์ 300 MB / วินาทีอาจใช้เวลา 100 วินาทีในการล้างข้อมูล) แม้ในอัตราดังกล่าวแล้ว OOM ก็อาจจะใจร้อนเกินไป หรือ OOM ฆ่า rsync ไม่เริ่มการทำงานของ FS flush เร็วพอ [หรือเลย] หรือ FS flush เกิดขึ้นเร็วพอ แต่มีการปล่อยหน้า "ขี้เกียจ" กลับไปที่พูลว่าง มีตัวเลือก / proc บางตัวที่คุณสามารถตั้งค่าให้ควบคุมพฤติกรรมการแคช FS ได้ [ฉันจำไม่ได้ว่ามีอะไร]

ลองทำการบูทด้วย mem = 4G หรือหมายเลขเล็ก ๆ สิ่งนี้อาจลดการใช้แคช FS และลดระยะเวลาการล้างข้อมูลเพื่อไม่ให้ OOM มองหาสิ่งอื่น ๆ ที่จะฆ่า (เช่นเวลาล้างจะลดลงจาก 100 วินาทีเป็น <1 วินาที) นอกจากนี้ยังอาจเปิดเผยข้อผิดพลาด OOM ที่ไม่สามารถจัดการ ram จริง> 4GB บนระบบ 32 บิตหรือบางอย่าง

นอกจากนี้ยังเป็นจุดสำคัญ: เรียกใช้เป็นที่ไม่ใช่ราก ผู้ใช้รูทไม่คาดว่าจะเคี้ยวทรัพยากรดังนั้นพวกเขาจึงได้รับการ จำกัด การให้อภัยมากขึ้น (เช่น 99% ของหน่วยความจำและ 95% สำหรับผู้ใช้ที่ไม่ใช่รูท) สิ่งนี้อาจอธิบายได้ว่าทำไม OOM ถึงอยู่ในสถานะเช่นนี้ นอกจากนี้ยังให้ OOM และ อัล มีพื้นที่ว่างมากขึ้นในการทำหน้าที่เรียกคืนหน่วยความจำ


ดูพื้นที่ SWAP ในระบบหน่วยความจำสูงมากแค่ไหน? - และคุณไม่ต้องการเห็นระบบของคุณใช้การแลกเปลี่ยน 63GB มันจะไม่สามารถใช้งานได้
Reinstate Monica - M. Schröder

1
swap> RAM มีประโยชน์จริง ๆ ถ้าคุณรันโดยไม่มี VM มากเกินไปดังนั้นเคอร์เนลต้องสำรองพื้นที่สว็อปสำหรับเพจที่ถูกจัดสรรจนกว่าจะสกปรกและต้องการหน้าฟิสิคัลจริงที่สำรองไว้ แนวปฏิบัติในปัจจุบันคือการอนุญาตให้มีคำสั่งเกินขนาดและเรียกใช้ด้วยพื้นที่สวอปจำนวนเล็กน้อยเพื่อเลื่อนหน้าเพจที่สัมผัสเมื่อเริ่มต้นเท่านั้นและไม่จำเป็นต้องใช้ในการทำงานปกติ overcommit = 0 ที่มีการสลับขนาดเล็กนั้นใช้ได้ถ้าคุณมี RAM จำนวนมากสำหรับระบบส่วนใหญ่
Peter Cordes

ดูเหมือนว่า rsync กำลังพยายามใช้> 32GB ดังนั้นจำเป็นต้องมีการสลับเพื่อใช้งาน นั่นคือ rsync จะใช้ 50GB สำหรับไฟล์นี้ 2x เป็นตัวชี้วัดที่ทดลองและเป็นจริงมา 30 ปีแล้ว เนื่องจากดิสก์ 6TB เป็น ~ $ 300 จึงไม่มีเหตุผลที่จะไม่ทำ มีอะไรอีกบ้างที่กำลังทำงานบนเซิร์ฟเวอร์นี้ที่เรียกรวมกันว่าจะเกินขีด จำกัด RAM?
Craig Estey

1
@CraigEstey การแลกเปลี่ยน 64 GB นั้นไร้สาระอย่างสมบูรณ์เนื่องจากที่ฉันกล่าวก่อนหน้านี้เราไม่มีกระบวนการผู้ใช้จำนวนมากเราต้องการแคชดิสก์เท่านั้นและเมื่อบันทึกของฉันปรากฏขึ้น ศูนย์. rsync ยังใช้ RAM 600KB แม้ในไฟล์ 50GB ความสับสนครั้งแรกของฉันคือการที่ linux อาจถือดิสก์แคชไว้อย่างจริงจัง และในที่สุดฉันต้องการเห็นตัวเลขหรือเอกสารเกี่ยวกับจำนวนหน่วยความจำที่เคอร์เนลใช้เพื่อติดตามพื้นที่สว็อปก่อนที่ฉันจะเพิ่มอีกในกล่องนี้
dataless

@dataless ฉันได้เพิ่มข้อมูลเพิ่มเติมที่อธิบายสิ่งที่เกิดขึ้นอย่างเต็มที่และทำไม rsync กำลังคว้าหน่วยความจำผ่าน malloc / mmap และจะไป 50GB ก่อนที่จะเสร็จสิ้น ดูส่วนการปรับปรุง มีการทดสอบที่สามารถพิสูจน์ / หักล้างสิ่งที่ฉันพูดและคุณสามารถข้ามการแลกเปลี่ยนที่เพิ่มเข้ามาเพื่อทดสอบ BTW ฉันได้รับการเขียนโปรแกรมเมล็ด / ไดรเวอร์สำหรับ 40 + ปีที่ - ฉันเพียงแค่อาจจะรู้ว่าบางสิ่งบางอย่างที่คุณไม่ได้ดังนั้นโปรดปานกลางโทน - ฉันกำลังพยายามที่จะช่วย
Craig Estey

2

clamd? ดูเหมือนว่าคุณกำลังใช้ ClamAV และในการเข้าถึงที่เปิดใช้งานสแกนที่เครื่องมือป้องกันไวรัสพยายามสแกนไฟล์ที่เปิดสำหรับไวรัสโดยการโหลดในหน่วยความจำเนื้อหาทั้งหมดของทุกไฟล์ที่เปิดโดยกระบวนการอื่น

ขึ้นอยู่กับท่าทางความปลอดภัยของคุณและความจำเป็นของการถ่ายโอนนี้คุณควรประเมินการปิดใช้งานการสแกน On-access ของ ClamAV ในขณะที่คุณทำการถ่ายโอน


ฉันไม่ทราบว่านี่เป็นสิ่งที่ clamav สามารถทำได้ ... แต่เราไม่เพียงสแกนไฟล์ที่ระบุจาก clamc เท่านั้น นอกจากนี้ 32- บิตดังนั้นไม่มีอันตรายจาก clamav hogging หน่วยความจำระบบทั้งหมด (คุณจะเห็นว่าทำไมเราคิดว่า 32 บิตยังเป็นความคิดที่ดีอยู่ใช่ไหม)
dataless

1
เคอร์เนล Linux รายงานว่า clamd เป็นกระบวนการที่มีการร้องขอการจัดสรรหน่วยความจำที่เรียกใช้ OOM killer - ClamAV นั้นเกือบเป็นสาเหตุรองแน่นอน (สาเหตุหลักคือหน่วยความจำไม่เพียงพอ) ไม่ว่าจะเป็นการสแกนแบบเข้าถึงหรือการกำหนดค่าอื่น ๆ สัญญาณทั้งหมดชี้ไปที่ ClamAV
อู

ครั้งต่อไปที่คุณเริ่ม rsync ให้เรียกใช้ด้านบนและตรวจสอบขนาดที่อยู่อาศัยของกระบวนการ clamd
อู

clamd เป็นกระบวนการแรกที่เรียกใช้ตัวฆ่า oom แต่ก็เป็นกระบวนการแรกที่ตายเพราะมันมีน้ำหนักเกือบ 42MB (หนึ่งในกระบวนการที่มีขนาดใหญ่กว่าบนเซิร์ฟเวอร์) oom_killer ทำงานซ้ำ ๆ หลังจากนี้จนกระทั่งถึงแม้กระทั่ง metalog ถูกฆ่าตาย
dataless
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.