SQL Server Express-ს აქვს სამი ჭერი, რომლის გათვალისწინებითაც სისტემა შეგიძლია დააპროექტო, და ერთი ნაკლული კომპონენტი, რომელიც უნდა ჩაანაცვლო. ჭერები ასეთია: 10 GB მონაცემი თითო ბაზაზე, დაახლოებით 1,4 GB buffer pool თითო ინსტანციაზე და ერთი სოკეტი ან ოთხი ბირთვი, რომელიც ნაკლებია. ნაკლული კომპონენტია SQL Server Agent, გამგეგმავი, რომელსაც სახელმძღვანელოების უმეტესობა თავისთავად ჩათვლის. ოთხივეს აქვს გამოსავალი: ყოველი ბაზა შეინახე მსუბუქად შეკუმშვით, არქივაციითა და ცალკე ბაზებით, სერვერის ზომა შეარჩიე იმ cache-ის მიხედვით, რომელსაც რეალურად მიიღებ, ხოლო დაგეგმილი სამუშაო ძრავიდან გაიტანე cron-ში, Task Scheduler-ში, აპლიკაციაში ან ჰოსტინგის საკუთარ განრიგში. ეს სტატია პრაქტიკული ნახევარია. რა ლიმიტებია და როდისაა დრო, Express დატოვო, ჯერ წაიკითხე SQL Server Express hosting: limits and when it is enough; აქ ვვარაუდობთ, რომ დარჩენა გადაწყვიტე.
რომელ ლიმიტს შეეჯახები პირველად#
რეალური დატვირთვების უმეტესობაში თანმიმდევრობა ასეთია: დისკი, შემდეგ მეხსიერება, შემდეგ Agent-ის არარსებობა, შემდეგ პროცესორი, ხოლო 10 GB-ის ჭერი ბოლოს მოდის ან საერთოდ არ მოდის. მონაცემთა ლიმიტი აშინებს, რადგან სათაურებშია, მაგრამ ტიპური საწარმოო ბაზა წლების შემდეგაც რამდენიმე ასეული მეგაბაიტიდან რამდენიმე გიგაბაიტამდეა. უფრო ადრე სხვა რამეები გკბენს: ტრანზაქციების ჟურნალი, რომელსაც არავინ ბექაფავს, აუდიტის ცხრილი შენახვის ვადის გარეშე და ღამის სამუშაო, რომელიც არასდროს გაშვებულა, რადგან გამშვები არ ჰყავდა.
ჯერ გაზომე. ორი მოთხოვნა გაჩვენებს, სად ხარ: პირველი იმ ბაზის მონაცემთა ფაილებს აჩვენებს, რომელსაც უკავშირდები, მეორე კი იმას, რამდენ cache-ს იკავებს თითო ბაზა.
SELECT name, type_desc, size * 8 / 1024 AS size_mb, FILEPROPERTY(name, 'SpaceUsed') * 8 / 1024 AS used_mbFROM sys.database_files;SELECT DB_NAME(database_id) AS db, COUNT(*) * 8 / 1024 AS cached_mbFROM sys.dm_os_buffer_descriptorsGROUP BY database_idORDER BY cached_mb DESC;ლიმიტი მონაცემთა ფაილების გამოყოფილ ზომაზე მოქმედებს, ამიტომ 10 240-თან size_mb შეადარე და არა used_mb. ჟურნალის ფაილები ლიმიტში არ შედის. თუ size_mb ჭერის ნახევარზე ნაკლებია და ნელა იზრდება, წლები გაქვს წინ; ძალა ბექაფებსა და განრიგს მოახმარე.
როგორ ჩაეტიო 10 GB-ში#
როცა მონაცემთა ფაილს ჭერის იქით გაზრდა სჭირდება, ზრდა უარყოფილია და ჩასმები, რომლებსაც ახალი გვერდები სჭირდება, შეცდომით ვარდება, კითხვა კი განაგრძობს მუშაობას. შუალედური გაფრთხილება არ არსებობს, ამიტომ ყველა გამოსავალი იმაზეა, რომ საზღვარს არ მიუახლოვდე. შრომატევადობის ზრდის მიხედვით:
გაარკვიე, რა არის რეალურად დიდი
სანამ რამეს გადაწყვეტ, გაუშვი ცხრილების ზომების მოთხოვნა. ზედა სამი ცხრილი თითქმის ყოველთვის ყველაფერს ხსნის.
SELECT TOP (10) s.name + '.' + t.name AS table_name, SUM(p.reserved_page_count) * 8 / 1024 AS reserved_mb, SUM(CASE WHEN p.index_id IN (0, 1) THEN p.row_count END) AS row_countFROM sys.dm_db_partition_stats AS pJOIN sys.tables AS t ON t.object_id = p.object_idJOIN sys.schemas AS s ON s.schema_id = t.schema_idGROUP BY s.name, t.nameORDER BY reserved_mb DESC;რეზერვირებული ზომა სტრიქონების რაოდენობას შეადარე. ათი მილიონი ვიწრო სტრიქონი 2 GB-ზე ნორმალურია. 40 000 სტრიქონი 3 GB-ზე ბინარულ მონაცემს ინახავს, ზომაშეზღუდულ ბაზაში კი ის არ უნდა ინახებოდეს.
შეკუმშე ცხრილები და ინდექსები
Row და page შეკუმშვა Express-ში მუშაობს (ის ყველა გამოცემაში ხელმისაწვდომია SQL Server 2016 SP1-დან). Page შეკუმშვა დიდ განმეორებად ცხრილს, მაგალითად აუდიტის ჟურნალს, ხშირად ნახევრად ამცირებს, ჩაწერისას და წაკითხვისას პროცესორის ოდნავ მეტი დატვირთვის ფასად. გადაკეთებამდე ძრავს სთხოვე დანაზოგის შეფასება:
EXEC sp_estimate_data_compression_savings @schema_name = 'dbo', @object_name = 'AuditLog', @index_id = NULL, @partition_number = NULL, @data_compression = 'PAGE';ALTER TABLE dbo.AuditLog REBUILD WITH (DATA_COMPRESSION = PAGE);გადაკეთებას სჭირდება სამუშაო ადგილი დაახლოებით ცხრილის ზომის და ის ჟურნალსაც ზრდის, ამიტომ გააკეთე, როცა ორივეგან მარაგი გაქვს, და წინასწარ გააკეთე ბექაფი. ფართო ცხრილებზე, რომლებიც ძირითადად იკითხება, clustered columnstore ინდექსი page შეკუმშვაზე გაცილებით მეტად კუმშავს, მაგრამ Express columnstore cache-ს 352 MB-ით ზღუდავს, columnstore კი ანალიტიკური სკანირებისთვის ივარგებს და არა წერტილოვანი ძებნისთვის, ამიტომ შეამოწმე შენს მოთხოვნებზე.
ცალკეული დიდი ტექსტური ან JSON სვეტებისთვის COMPRESS() და DECOMPRESS() GZIP-ს პირდაპირ T-SQL-ში იყენებს და შედეგს varbinary(max) სვეტში ინახავს. დიდ მონაცემზე ის ადგილს ზოგავს; ფასი ისაა, რომ ასეთ სვეტს პირდაპირ ვეღარ დაინდექსებ და ვეღარ მოძებნი.
გაიტანე ბინარული მონაცემი
varbinary(max)-ში შენახული სურათები, PDF-ები და ატვირთული დოკუმენტები 10 GB-იან ბაზას სხვა ყველაფერზე სწრაფად ავსებს, და თითოეული მათგანი შენს 1,4 GB buffer pool-საც გადის და აუცილებელ გვერდებს განდევნის. ფაილი შეინახე ობიექტურ საცავში ან დისკზე, ცხრილში კი დატოვე მხოლოდ გასაღები, ზომა და შიგთავსის ტიპი. თუ საცავი ბაზის გვერდით გინდა, RE:NODE-ს ცალკე ხაზად აქვს S3-თან თავსებადი ობიექტური საცავი; ნებისმიერი S3 endpoint-ი მუშაობს, პრინციპი ერთია.
დაარქივე პარტიებად
ძველი სტრიქონები, რომლებიც უნდა შეინახო, მაგრამ იშვიათად იკითხება, იმავე ინსტანციის მეორე ბაზაში შეიძლება გადავიდეს, რომელსაც თავისი 10 GB აქვს. T-SQL ბაზებს შორის partition switch-ს ვერ აკეთებს, ამიტომ გადაიტანე მცირე პარტიებით, რომლებიც წყაროდან შლიან და არქივში ერთი ოპერატორით სვამენ:
WHILE 1 = 1BEGIN DELETE TOP (5000) FROM app.dbo.AuditLog OUTPUT deleted.* INTO archive.dbo.AuditLog WHERE CreatedAt < DATEADD(MONTH, -18, SYSUTCDATETIME()); IF @@ROWCOUNT = 0 BREAK;ENDOUTPUT ... INTO-სთვის სამიზნე ცხრილს იგივე სვეტები უნდა ჰქონდეს და ჩართული ტრიგერები ან გარე გასაღებები არ უნდა გააჩნდეს. მცირე პარტიები თითოეულ ტრანზაქციას მოკლეს ინახავს, ამიტომ ჟურნალი არ ფართოვდება და ბლოკირებები სწრაფად თავისუფლდება. გაუშვი ეს დაგეგმილი სამუშაოდან (იხილე ქვემოთ) და არა ხელით.
წაშალე ის, რასაც ღირებულება არ აქვს
ვადაგასული სესიები, პაროლის აღდგენის ტოკენები, შენახვის ვადაზე ძველი "წაშლილად" მონიშნული სტრიქონები და დეტალური მოთხოვნების ჟურნალები ბაზაში სამუდამოდ არ უნდა ცხოვრობდეს. თითო ცხრილისთვის განსაზღვრე შენახვის ვადა, დაწერე თითო გასუფთავების ოპერატორი და დაგეგმე. ეს ყველაზე იაფი გამოსავალია და ბაზების უმეტესობა მას არასდროს იყენებს.
მოაცილე გამოუყენებელი ინდექსები
ინდექსები მონაცემთა ზომაში ითვლება. sys.dm_db_index_usage_stats ბოლო გადატვირთვიდან ყოველი ინდექსის წაკითხვებსა და ჩაწერებს აჩვენებს. ინდექსი ბევრი ჩაწერით და წაკითხვის გარეშე წმინდა ხარჯია. მას მხოლოდ მაშინ ენდე, რაც სერვერმა სრული ბიზნეს ციკლი გაიარა (თვიური რეპორტი ინდექსის ერთადერთი მომხმარებელი შეიძლება იყოს), რადგან მრიცხველები გადატვირთვისას ნულდება.
გაყავი დანიშნულების მიხედვით
ერთი ბაზა თითო აპლიკაციაზე და ცალკე ბაზა რეპორტებისთვის ან არქივისთვის შეუზღუდავად მზარდი მონაცემისთვის კარგი დიზაინია ნებისმიერ გამოცემაზე, Express-ზე კი ის მარაგსაც ამრავლებს. ლიმიტი ბაზაზე მოქმედებს და არა ინსტანციაზე. ერთ ინსტანციაზე ბაზათაშორისი მოთხოვნები სამნაწილიანი სახელებით მუშაობს (archive.dbo.AuditLog), ამიტომ გაყოფა იშვიათად ნიშნავს მოთხოვნების გადაწერას.
შეკუმშვა ფაილისა, ერთხელ
დიდი გასუფთავების შემდეგ ფაილი დიდი რჩება. DBCC SHRINKFILE ადგილს აბრუნებს, მაგრამ ინდექსებს ძლიერ ფრაგმენტირებს, ამიტომ გაუშვი ერთხელ დიდი გასუფთავების შემდეგ, ძირითადი ინდექსები თავიდან ააგე და განრიგში არასდროს ჩასვა. რადგან ლიმიტი გამოყოფილ ზომაზეა, ნახევრად ცარიელი 9,8 GB ფაილი ჭერთან ახლოს რჩება, სანამ არ შეკუმშავ.
დისკიც ლიმიტია და პატარა გეგმაზე ის პირველი მოდის#
10 GB-ის ჭერი ლიცენზიის წესია; დისკი ფიზიკური შეზღუდვაა და ჰოსტინგზე ის ჩვეულებრივ უფრო მცირეა. 10 GB-იან ბაზას ადგილი სჭირდება ჟურნალისთვის, tempdb-სთვის, იმ ბექაფებისთვის, რომლებიც იმავე ტომზე დევს, სანამ გარეთ არ გაიტან, და ოპერაციული სისტემის საკუთარი ფაილებისთვის. RE:NODE-ზე SQL Server-ის ხაზი Express Starter-იდან (2 GB მეხსიერება, 10 GB დისკი, 1 vCPU) Express Max-მდე (6 GB მეხსიერება, 80 GB დისკი, 4 vCPU) გრძელდება, თვეში $6-დან. არითმეტიკა მარტივია: 10 GB დისკზე 10 GB ბაზას ვერასდროს მიაღწევ, 80 GB-ზე კი რამდენიმე ბაზას ჭერთან ახლოს გაუშვებ.
ამიტომ გეგმა ჯერ დისკის მიხედვით აირჩიე. ერთი ბაზის უხეში ბიუჯეტი, რომელიც მაქსიმუმზე N GB იქნება: N მონაცემზე, N/4-დან N/2-მდე ჟურნალზე, ერთი სრული ბექაფის ფაილი (დაახლოებით N, რადგან Express ბექაფებს არ კუმშავს), სანამ სერვერზე დევს, და რამდენიმე GB tempdb-სა და მარაგზე. მეორე ასლი მანქანის გარეთაა, სწორედ ამაშია აზრი; იხილე განრიგის თავი.
როგორ იცხოვრო 1,4 GB buffer pool-ით#
მეხსიერების ლიმიტი buffer pool-ს ეხება, ანუ მონაცემთა გვერდების cache-ს. პროცესი მთლიანობაში მეტს იყენებს, რადგან გეგმები, კავშირები და დახარისხება ლიმიტში არ შედის. პრაქტიკაში აქედან ორი რამ გამომდინარეობს.
პირველი: დაახლოებით 4 GB-ზე მეტი მეხსიერების მქონე სერვერი ძრავს არ ეხმარება, რადგან cache 1410 MB-ზე ჩერდება. მეხსიერება მხოლოდ იმ ზღვრამდე იყიდე, სადაც buffer pool შეიძლება აივსოს და ოპერაციულ სისტემას ძრავთან ერთად მარაგი რჩება; მერე დისკი იყიდე. RE:NODE-ის გეგმები ამას ასახავს: Express Pro-დან Express Max-ზე გადასვლა (4-დან 6 GB მეხსიერებამდე) ძირითადად დისკისა და ოთხივე ბირთვისთვისაა.
მეორე: 1,4 GB-ზე დიდი სამუშაო სიმრავლე დისკიდან უფრო ხშირად იკითხება. NVMe, რომელიც RE:NODE-ის ყველა გეგმაზეა, ამას ბრუნვად დისკებზე ნაკლებად მტკივნეულს ხდის, მაგრამ კითხვების შემცირება მაინც შეგიძლია:
- უფრო ვიწრო სტრიქონები და ინდექსები. დამფარავი ინდექსი მხოლოდ იმ სვეტებით, რომლებიც ცხელ მოთხოვნას სჭირდება, cache-ირებულ გვერდზე მეტ სასარგებლო სტრიქონს ათავსებს. შეკუმშვა გვერდზე მეტ სტრიქონს ტენის და cache-სა და დისკს ორივეს ადიდებს.
- ნაკლები, მაგრამ უკეთესი ინდექსები. ყოველი ინდექსი, რომელსაც ინახავ, იმავე 1,4 GB-სთვის ეჯიბრება. Indexes and execution plans განმარტავს, როგორ წაიკითხო გეგმა და მოაცილო ის, რაც არ გეხმარება.
- **არანაირი
SELECT *.** ფართო სტრიქონების წამოღება, რომლებიც არ გჭირდება, cache-ში ბინარულ მონაცემსა და იშვიათად საჭირო სვეტებს ათრევს. - იპოვე ძვირი მოთხოვნები. გვერდების კითხვების უმეტესობას ჩვეულებრივ რამდენიმე მოთხოვნა იწვევს. Query Store and slow queries გვიჩვენებს, როგორ ვიპოვოთ ისინი Express-ში, სადაც Query Store ხელმისაწვდომია.
- cache-ირება აპლიკაციაში. საცნობარო მონაცემი, რომელიც არ იცვლება, აპლიკაციის მეხსიერებაში ან Valkey-ში უნდა ინახებოდეს და არა SQL Server-ის მოთხოვნაში ყოველ მოთხოვნაზე.
შეზღუდე ინსტანცია, რომ დანარჩენებს მეხსიერება ეყოთ
ნაგულისხმევ ინსტალაციაზე SQL Server ცდილობს მთელი მიცემული მეხსიერება დაიკავოს გამოცემის ლიმიტამდე, Express-ში კი buffer pool 1410 MB-ზე ჩერდება. თუ კონტეინერს ან მანქანას ამის გარდა ცოტა მეხსიერება აქვს, ცხადი ჭერი დააყენე, რომ ოპერაციულმა სისტემამ თავისი წილი შეინარჩუნოს:
EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'max server memory (MB)', 1536;RECONFIGURE;შეგიძლია თუ არა ამის შეცვლა, დამოკიდებულია იმაზე, როგორ უშვებს ჰოსტინგი ინსტანციას და რა ლოგინი გაქვს, ამიტომ დაეყრდნობამდე შეამოწმე. RE:NODE-ზე გეგმის მეხსიერების ლიმიტს კონტეინერი ახორციელებს: მეხსიერების ზღვარზე ბირთვი კონტეინერს აჩერებს და ის სუფთად ხელახლა იწყება, swap-ში ჩავარდნის ნაცვლად. ეს ქცევა სტაბილურობისთვის უპირატესობაა და მარაგის დატოვების მიზეზი. აირჩიე გეგმა, რომლის მეხსიერებაც კომფორტულად აღემატება SQL Server პროცესის საჭიროებას, და მეხსიერების გრაფიკს Console ჩანართზე უყურე, ვარაუდის ნაცვლად.
ოთხი ბირთვის ლიმიტი#
Express იყენებს ერთ სოკეტს ან ოთხ ბირთვს, რომელიც ნაკლებია, ამიტომ რვაბირთვიანი ჰოსტი მას არ აჩქარებს. გამოსავალი ბირთვების კარგად გამოყენებაა და არა მეტის სურვილი:
- ჯერ ყველაზე ცუდი მოთხოვნები გაასწორე. ინდექსის არარსებობა, რომელიც ყოველ მოთხოვნაზე seek-ს scan-ად აქცევს, უფრო მეტ პროცესორს ხარჯავს, ვიდრე სხვაგან ნებისმიერი მორგება.
- პარალელიზმი გონივრულად დაიჭირე. პარალელური გეგმები ოთხბირთვიან ინსტანციაზე დანარჩენ სამუშაოს შეიძლება ჩაახშობდეს. სერვერული პარამეტრი
max degree of parallelism(EXEC sp_configure 'max degree of parallelism', 2;გაფართოებული პარამეტრების ჩართვის შემდეგ) პატარა სერვერებზე გავრცელებული არჩევანია, მაგრამ შეამოწმე შენს დატვირთვაზე და რიცხვი ბრმად არ გადაიკოპირო. - რეპორტები პიკის საათებიდან გაიტანე. მძიმე აგრეგაციები დღის მშვიდ ნაწილში უნდა შესრულდეს, და ესეც კიდევ ერთი მიზეზია, რომ გამგეგმავი გქონდეს.
- გადმოიტანე ის, რაც მოთხოვნა არ არის. სრულტექსტური ძებნა, cache-ირება და რიგები უკეთესია სხვა ინსტრუმენტს მივანდოთ, ვიდრე SQL Server-ს ყველაფრის კეთება ვაიძულოთ.
RE:NODE-ზე გეგმის პროცესორი ნაყიდ წილზე მკაცრი შეზღუდვაა, ამიტომ Express Starter-ზე სულ ერთი vCPU გაქვს და არა ოთხი. სერვერი 100%-ზე ნელია და არა გატეხილი, და ამის გამო მას არასდროს აჩერებენ. თუ პროცესორის გრაფიკი პიკის საათებში ჭერს ეჯახება, ეს ნიშანია, რომ მოთხოვნები მოარგო ან უფრო მაღალ გეგმაზე გადახვიდე.
SQL Server Agent-ის გარეშე: რით ჩავანაცვლოთ#
Agent-ის სამუშაოს ნაბიჯი არის ბრძანება, განრიგი და დასრულების სტატუსი. ნებისმიერი გამგეგმავი, რომელსაც sqlcmd-ის გაშვება შეუძლია, იგივეს იძლევა. კარგავ ჩაშენებულ ისტორიას, გაფრთხილებებსა და ფოსტას და მათ საკუთარი ლოგირებით ანაცვლებ. ვარიანტები მარტივიდან შრომატევადისკენ:
ჰოსტინგის საკუთარი განრიგი, ბექაფებისთვის
RE:NODE-ზე ყოველ სერვერს აქვს Schedules ჩანართი: cron გამოსახულება, შემდეგ მიმდევრობით დალაგებული ამოცანები დაყოვნებებით, სადაც ამოცანა არის კონსოლის ბრძანება, ბექაფი ან კვების ქმედება. ბექაფის ამოცანა სერვერის ღამის ასლს აკეთებს შენი სკრიპტის შენახვის გარეშე. SQL Server-ის გეგმებს 1-დან 4-მდე ბექაფის სლოტი აქვს; ბექაფები იმ მანქანის გარეთ ინახება, რომელსაც იცავს, შეიძლება ბრუნვისგან დაიბლოკოს, ჩამოიტვირთოს და ღილაკით აღდგეს. ეს ფარავს ყველაზე მნიშვნელოვან სამუშაოს, რასაც Agent ჩვეულებრივ აკეთებს. ნუ გაიგებ ამას, როგორც პანელიდან თვითნებური T-SQL-ის გაშვებას; ამისთვის შემდეგი ვარიანტები გამოიყენე. სინტაქსს აღწერს Cron expressions explained, ხოლო რა ჩასვა განრიგში, გვკარნახობს scheduled tasks worth having.
cron პლუს sqlcmd
ნებისმიერ Linux მანქანაზე, რომელსაც აკონტროლებ (პატარა VDS, CI runner, აპლიკაციის სერვერი), crontab-ის ხაზი სკრიპტის ფაილს ბაზაზე უშვებს. პაროლი ბრძანების სტრიქონიდან გარეთ დატოვე გარემოს ცვლადში SQLCMDPASSWORD:
$ export SQLCMDPASSWORD='the-generated-password'$ sqlcmd -S db.example.net,14330 -U sa -d app -C -b -i /opt/jobs/purge.sql-S იღებს host,port-ს მძიმით, -C სერვერის სერტიფიკატს ენდობა (საჭიროა თვითხელმოწერილზე და მისაღებია მხოლოდ მაშინ, თუ ჰოსტი იცნობ), -b აიძულებს sqlcmd-ს სკრიპტის შეცდომისას არანულოვანი კოდი დააბრუნოს, ხოლო -i სკრიპტის ფაილს ასახელებს. სწორედ დასრულების კოდი აძლევს cron-ს ან შემომგარს საშუალებას, გაიგოს, რომ რაღაც აირია. ალმებსა და ერთნაირი სახელის ორ განსხვავებულ პროგრამას აღწერს sqlcmd and bcp.
crontab-ის ჩანაწერი ღამის გასუფთავებისთვის 03:15-ზე, გამოტანით ჟურნალის ფაილში:
15 3 * * * /opt/jobs/run-sql.sh purge.sql >> /var/log/sqljobs.log 2>&1გამოძახება პატარა shell სკრიპტში შეახვიე, რომელიც წარუმატებლობისას არანულოვანი კოდით სრულდება და შეტყობინებას გიგზავნის (ელფოსტა, webhook ჩატში), რომ ჩუმი წარუმატებლობა თვალსაჩინო გახდეს. ეს Agent-ისა და Database Mail-ის გაფრთხილებების შემცვლელია, რომლებიც Express-ს არ აქვს.
Windows Task Scheduler
თუ შენი აპლიკაცია Windows-ზე მუშაობს, იგივეს აკეთებს დაგეგმილი ამოცანა, რომელიც sqlcmd -S ... -i script.sql-ს უშვებს. დააყენე, რომ მომხმარებლის შესვლის მიუხედავად გაეშვას, ავტორიზაციის მონაცემები სკრიპტში კი არა, ამოცანაში შეინახე, და დააყენე გონივრული ლიმიტი "შეაჩერე ამოცანა, თუ უფრო დიდხანს მუშაობს", რომ გაჭედილმა კავშირმა ხვალინდელი გაშვება არ დაბლოკოს.
აპლიკაციის შიგნით
.NET-ში hosted service, Hangfire ან Quartz.NET სამუშაო, Node-ის cron ბიბლიოთეკა ან ნებისმიერ ენაზე ფონური worker განრიგით შეუძლია მომსახურების T-SQL-ის გაშვება, და მათ ერთი უპირატესობა აქვთ: connection string-ი და logger-ი უკვე აქვთ. კავშირის მხარეს ფარავს .NET with PostgreSQL, MySQL or SQL Server. სუსტი წერტილი ისაა, რომ თუ აპლიკაცია გამორთულია, სამუშაოც გამორთულია, ხოლო სამუშაო, რომელიც გაფართოებული აპლიკაციის ყველა ეგზემპლარში გადის, რამდენჯერმე სრულდება. გამოიყენე გასუფთავებისა და სტატისტიკისთვის, მაგრამ ბექაფების ერთადერთ შემსრულებლად ნუ გახდი.
რის კეთება არ ღირს
ნუ გაუშვებ კავშირს, რომელიც WAITFOR DELAY ციკლში ჰკიდია მოთხოვნის ფანჯარაში ან გრძელ პროცედურაში, გამგეგმავის იმიტაციისთვის. ის კავშირსა და სესიას სამუდამოდ იკავებს, სერვერის გადატვირთვისას ჩუმად კვდება და წარუმატებლობაზე არაფერს გეუბნება. იგივე ეხება ტრიგერს, რომელიც ყოველ ჩასმაზე მძიმე სამუშაოს აკეთებს სამუშაოს ასარიდებლად: ის ხარჯს შენი მომხმარებლების მოთხოვნებში გადააქვს.
სამუშაოების ჩანაცვლება, რასაც Agent ჩვეულებრივ აკეთებდა#
Agent-ის ინსტალაციების უმეტესობა ოთხი სახის სამუშაოს უშვებს. თითოეულს პირდაპირი ეკვივალენტი აქვს.
| Agent-ის სამუშაო | ჩანაცვლება Express-ზე |
|---|---|
| ღამის სრული ბექაფი | ჰოსტინგის განრიგის ბექაფი ან BACKUP DATABASE cron-იდან |
| ჟურნალის ბექაფი ყოველ 15-60 წუთში | BACKUP LOG სკრიპტი cron-იდან ან მარტივი აღდგენის მოდელი |
| ინდექსებისა და სტატისტიკის მომსახურება | კვირეული სკრიპტი ან მზა სკრიპტების ნაკრები |
| გასუფთავება, არქივი, რეპორტის ცხრილები | პარტიული T-SQL cron-იდან ან აპლიკაციიდან |
ნატიური ბექაფებისთვის ამ ზომის სკრიპტის ფაილი საკმარისია, შემდეგი ნაბიჯი კი შედეგის სხვაგან გადაკოპირებაა:
BACKUP DATABASE [app] TO DISK = N'/var/opt/mssql/backup/app.bak' WITH INIT, CHECKSUM, STATS = 10;RESTORE VERIFYONLY FROM DISK = N'/var/opt/mssql/backup/app.bak' WITH CHECKSUM;გზა Linux-ის ინსტალაციაზე ბექაფების ნაგულისხმევი დირექტორიაა; ჰოსტინგზე ის შეიძლება განსხვავდებოდეს. .bak ფაილი ბაზის იმავე დისკზე ბეჭდვის შეცდომისგან გიცავს და არა დისკის დაკარგვისგან. აღდგენას, WITH MOVE-სა და ობოლ მომხმარებლებს აღწერს SQL Server backup and restore. რადგან Express ბექაფებს თვითონ არ კუმშავს, ფაილი ჩაწერის შემდეგ შეკუმშე (gzip ან zstd იმავე სკრიპტში), სანამ მანქანიდან გაიტან.
ჟურნალის ბექაფები მხოლოდ მაშინაა საჭირო, თუ ბაზა აღდგენის სრულ მოდელშია. თუ დროის წერტილზე აღდგენა არ გჭირდება, ALTER DATABASE [app] SET RECOVERY SIMPLE; ამ სამუშაოს მთლიანად აქრობს და ჟურნალის გაუკონტროლებელ ზრდას აცილებს, რომელიც აღწერილია recovery models and log growth-ში. თუ გჭირდება, დაგეგმე BACKUP LOG და შეამოწმე აღდგენა დროის წერტილზე, რადგან ჟურნალის ჯაჭვი, რომელიც არასდროს აღგიდგენია, ჰიპოთეზაა.
ინდექსებისა და სტატისტიკის მომსახურებაში ძველი რჩევებზე ნაკლები გააკეთე. სტატისტიკის ავტომატური განახლება ნაგულისხმევად ჩართულია და პატარა ბაზებისთვის საკმარისია. ფრაგმენტაცია NVMe-ზე თითქმის არ აწუხებს; ინდექსი მაშინ ააგე თავიდან ან გადაალაგე, როცა შეგიძლია აჩვენო, რომ ის კონკრეტულ მოთხოვნას ანელებს. თუ მზა პროცედურა გინდა, Ola Hallengren-ის უფასო და ფართოდ გამოყენებული მომსახურების გადაწყვეტა უბრალო T-SQL-ია, რომელიც Express-ზე მუშაობს, სანამ მას რაღაც გარედან იძახებს, და ამ თავის აზრიც ეს არის.
განრიგი პრაქტიკაში: ღამის სამუშაო თავიდან ბოლომდე#
ერთად აღებული, Express ბაზისთვის ღამის გონივრული რუტინა ასე გამოიყურება:
- 02:00 - ჰოსტინგის განრიგი სერვერის ბექაფს უშვებს (ან შენი სკრიპტი
BACKUP DATABASE-ს ასრულებს და ფაილს გადააკოპირებს). - 03:15 - cron მანქანაზე, რომელსაც აკონტროლებ, გასუფთავებისა და არქივაციის სკრიპტს უშვებს
sqlcmd -b-ით. - 03:45 - იგივე მანქანა უშვებს
sp_updatestats-ს, თუ მოძველებული სტატისტიკა გინახავს, და ზომის მოთხოვნას, რომელიც ბაზის ზომას ჟურნალში ან მეტრიკაში წერს. - ყოველკვირა - უახლესი ბექაფის აღდგენა სატესტო ბაზაში, შემდეგ
DBCC CHECKDBაღდგენილ ასლზე და არა ცოცხალ ბაზაზე. - ყოველთვე - წაიკითხე ზომის ტრენდი და გადაწყვიტე, შეკუმშო, დაარქივო თუ უფრო მაღალ გეგმაზე გადახვიდე.
სამუშაოები დროში გაანაწილე, რომ გრძელი გასუფთავება ბექაფს არასდროს გადაეფაროს. ოთხბირთვიან ინსტანციაზე 1,4 GB cache-ით ორი მძიმე სამუშაო ერთდროულად აპლიკაციას გადაფარვის მთელ ხანგრძლივობაზე შეანელებს.
გადასვლა უფრო დიდ გეგმაზე მონაცემთა დაკარგვის გარეშე#
როცა გამოსავალი აღარ ჰყოფნის, უფრო მაღალ გამოცემაზე ან სხვა ჰოსტინგზე გადასვლა ბექაფი და აღდგენაა: Express-ის .bak იმავე ან უფრო ახალი ვერსიის Standard-ზე ან Enterprise-ზე გარდაქმნის გარეშე აღდგება. გადასვლა დაგეგმე მანამდე, სანამ ჭერი აგაძულებს. Migrating a database to SQL Server hosting ვერსიების წესებს საპირისპირო მიმართულებით აღწერს, ხოლო which database should I use ძრავებს ადარებს, თუ ნამდვილი პასუხი სხვა ბაზაა. RE:NODE-ზე გეგმის შეცვლა სერვერს თავიდან არ აშენებს, ამიტომ პატარა Express გეგმიდან უფრო დიდზე გადასვლა დისკისთვის მიგრაცია არ არის.
FAQ#
როგორ ჩავეტიო ყველაზე სწრაფად 10 GB ლიმიტში?
იპოვე ყველაზე დიდი ცხრილები, წაშალე ან დაარქივე არასაჭირო სტრიქონები რამდენიმე ათასიანი პარტიებით, შენახული ფაილები ობიექტურ საცავში გადაიტანე და დარჩენილი DATA_COMPRESSION = PAGE-ით შეკუმშე. ჭერამდე მისული ბაზების უმეტესობა ჟურნალებითა და ბინარული მონაცემებითაა სავსე.
შეიძლება თუ არა SQL Server Express-ში დაგეგმილი სამუშაოების გაშვება?
დიახ, ძრავის გარედან. გამოიყენე sqlcmd cron-იდან ან Task Scheduler-იდან, სამუშაოების შემსრულებელი აპლიკაციაში ან ჰოსტინგის საკუთარი განრიგი ბექაფებისთვის. მხოლოდ თავად SQL Server Agent აკლია.
შედის თუ არა ტრანზაქციების ჟურნალი 10 GB-ში?
არა, მხოლოდ მონაცემთა ფაილები ითვლება. ჟურნალს დისკის ადგილი ზღუდავს, ამიტომ აღდგენის სრულ მოდელში უკონტროლო ჟურნალი რეალური რისკია და ამიტომაა დისკი მნიშვნელოვანი გეგმის არჩევისას.
გაზრდის თუ არა მეტი RAM 1,4 GB buffer pool-ის ლიმიტს?
არა. Buffer pool თითო ინსტანციაზე 1410 MB-ზე ჩერდება, სერვერს რამდენიც არ უნდა მეხსიერება ჰქონდეს. დამატებითი მეხსიერება მხოლოდ პროცესის დანარჩენ ნაწილს და ოპერაციულ სისტემას ეხმარება, ამიტომ ფული დისკზე ან უკეთეს ინდექსებზე დახარჯე.
როგორ მივიღო გაფრთხილებები Database Mail-ის გარეშე?
სამუშაოს სკრიპტი sqlcmd -b-ით წარუმატებლობისას არანულოვან კოდს დააბრუნებინე, შემომგარმა კი ამ დროს შეტყობინება ელფოსტაზე ან ჩატის webhook-ზე გაგზავნოს. გაფრთხილება მაშინ შენს გამგეგმავშია და არა ძრავში.


