பவர்ஷெல்லில் இருந்து எம்எஸ் எஸ்.கியூ.எல் உடன் பணிபுரிதல் Linux

இந்த கட்டுரை முற்றிலும் நடைமுறை மற்றும் எனது சோகமான கதைக்கு அர்ப்பணிக்கப்பட்டுள்ளது

தயாராகிறது ஜீரோ டச் PROD எல்லோரும் பரபரப்பாகப் பேசிக்கொண்டிருந்த RDS (MS SQL)-க்காக, நான் தானியக்கம் குறித்த ஒரு விளக்கக்காட்சியை (POC - Proof of Concept) வழங்கினேன்: அது ஒரு பவர்ஷெல் ஸ்கிரிப்டுகளின் தொகுப்பு. விளக்கக்காட்சிக்குப் பிறகு, இடி முழக்கம் போன்ற நீண்ட கைதட்டல், பின்னர் எழுந்து நின்று பாராட்டும் நிலைக்கு உயர்ந்தது ஓய்ந்ததும், அவர்கள் என்னிடம் சொன்னார்கள் - இதெல்லாம் ஒருபுறம் நல்லதுதான், ஆனால் சித்தாந்தக் காரணங்களுக்காக, நமது ஜென்கின்ஸ் ஸ்லேவ்கள் அனைத்தும் கீழ்மட்டத்தில் இயங்கிக்கொண்டிருக்கின்றன. Linux!

இது சாத்தியம்தானா? இவ்வளவு சூடான, குழாய் போன்ற ஒரு DBA-வை அடியிலிருந்து எடுப்பது Windows மற்றும் அதை பவர்ஷெல்லின் மிக அடர்த்தியான பகுதிக்குள் செருகவும் Linuxஅது கொடுமையானது அல்லவா?

பவர்ஷெல்லில் இருந்து எம்எஸ் எஸ்.கியூ.எல் உடன் பணிபுரிதல் Linux
நான் இந்த விசித்திரமான தொழில்நுட்பக் கலவைக்குள் மூழ்க வேண்டியிருந்தது. இயல்பாகவே, எனது 30-க்கும் மேற்பட்ட ஸ்கிரிப்டுகள் அனைத்தும் வேலை செய்வதை நிறுத்திவிட்டன. எனக்கு ஆச்சரியமளிக்கும் வகையில், ஒரே வேலை நாளில் எல்லாவற்றையும் சரிசெய்துவிட்டேன். இந்தச் செய்தி இன்னும் நினைவில் இருக்கும்போதே இதை எழுதுகிறேன். எனவே, பவர்ஷெல் ஸ்கிரிப்டுகளை இடம்பெயரச் செய்யும்போது நீங்கள் என்னென்ன சிக்கல்களைச் சந்திக்க நேரிடலாம்? Windows கீழ் Linux?

sqlcmd vs Invoke-SqlCmd

அவற்றுக்கிடையேயான முக்கிய வேறுபாட்டை நான் உங்களுக்கு நினைவூட்டுகிறேன். நல்ல பழைய பயன்பாடு sqlcmd இது லினக்ஸின் கீழும் கிட்டத்தட்ட ஒரே மாதிரியான செயல்பாட்டுடன் செயல்படுகிறது. -Q ஐ இயக்க வினவலை அனுப்புகிறோம், உள்ளீட்டு கோப்பை -i ஆகவும், வெளியீட்டை -o ஆகவும் அனுப்புகிறோம். ஆனால் கோப்பு பெயர்கள், நிச்சயமாக, வழக்கு உணர்திறன் செய்யப்படுகின்றன. நீங்கள் -i ஐப் பயன்படுத்தினால், கோப்பில் இறுதியில் எழுதவும்:

GO
EXIT

இறுதியில் EXIT இல்லை என்றால், sqlcmd உள்ளீட்டிற்காக காத்திருக்கும், மற்றும் அதற்கு முன் வெளியேறு மாட்டேன் GO, கடைசி கட்டளை வேலை செய்யாது. வெளியீட்டு கோப்பில் அனைத்து வெளியீடு, தேர்வுகள், செய்திகள், அச்சு, முதலியன உள்ளன.

Invoke-SqlCmd ஆனது DataSet, DataTables அல்லது DataRows என முடிவை உருவாக்குகிறது. எனவே, ஒரு எளிய தேர்வின் முடிவை நீங்கள் செயலாக்கினால், நீங்கள் பயன்படுத்தலாம் sqlcmd, அதன் வெளியீட்டைப் பாகுபடுத்தி, சிக்கலான ஒன்றைப் பெறுவது கிட்டத்தட்ட சாத்தியமற்றது: இதற்காக உள்ளது அழைப்பு-SqlCmd. ஆனால் இந்த அணிக்கு அதன் சொந்த நகைச்சுவைகளும் உள்ளன:

  • நீங்கள் ஒரு கோப்பை அவளுக்கு மாற்றினால் -உள்ளீடு கோப்பு, பின்னர் வெளியேறு தேவையில்லை, மேலும், இது தொடரியல் பிழையை உருவாக்குகிறது
  • - வெளியீடு கோப்பு இல்லை, கட்டளை ஒரு பொருளாக முடிவை உங்களுக்கு வழங்குகிறது
  • சேவையகத்தைக் குறிப்பிட இரண்டு தொடரியல்கள் உள்ளன: -ServerInstance -பயனர்பெயர் -கடவுச்சொல் - தரவுத்தளம் மற்றும் மூலம் -இணைப்பு சரம். விந்தை போதும், முதல் வழக்கில் 1433 ஐத் தவிர வேறு ஒரு துறைமுகத்தைக் குறிப்பிட முடியாது.
  • உரை வெளியீடு, PRINT என தட்டச்சு செய்யவும், இது வெறுமனே "பிடிபட்டது" sqlcmdஐந்து அழைப்பு-SqlCmd ஒரு பிரச்சனை
  • மற்றும் மிக முக்கியமாக: பெரும்பாலும் உங்கள் லினக்ஸில் இந்த cmdlet இல்லை!

மேலும் இதுதான் முக்கிய பிரச்சனை. மார்ச் மாதத்தில் மட்டும் இந்த cmdlet விண்டோஸ் அல்லாத இயங்குதளங்களுக்கு கிடைத்தது, இறுதியாக நாம் முன்னேறலாம்!

மாறி மாற்று

sqlcmd ஆனது -v ஐப் பயன்படுத்தி மாறி மாற்றீட்டைக் கொண்டுள்ளது, எடுத்துக்காட்டாக இது போன்றது:

# $conn содержит начало команды sqlcmd
$cmd = $conn + " -i D:appsSlaveJobsKillSpid.sql -o killspid.res 
  -v spid =`"" + $spid + "`" -v age =`"" + $age + "`""
Invoke-Expression $cmd

SQL ஸ்கிரிப்ட்டில் நாம் மாற்றுகளைப் பயன்படுத்துகிறோம்:

set @spid=$(spid)
set @age=$(age)

எனவே இதோ. * நிக்ஸில் மாறி மாற்றுகள் வேலை செய்யாது. அளவுரு -v புறக்கணிக்கப்பட்டது. யு அழைப்பு-SqlCmd புறக்கணிக்கப்பட்டது - மாறிகள். மாறிகளைக் குறிப்பிடும் அளவுரு புறக்கணிக்கப்பட்டாலும், மாற்றீடுகள் தாங்களாகவே செயல்படுகின்றன - ஷெல்லில் இருந்து எந்த மாறிகளையும் நீங்கள் பயன்படுத்தலாம். இருப்பினும், நான் மாறிகளால் புண்படுத்தப்பட்டேன், மேலும் SQL ஸ்கிரிப்டுகள் குறுகியதாக இருப்பதால், அவற்றைச் சார்ந்து இருக்க வேண்டாம் என்று முடிவு செய்தேன், மேலும் முரட்டுத்தனமாகவும் பழமையானதாகவும் செயல்பட்டேன்:

# prepend the parameters  
"declare @age int, @spid int" | Add-Content "q.sql"
"set @spid=" + $spid | Add-Content "q.sql"
"set @age=" + $age | Add-Content "q.sql"

foreach ($line in Get-Content "Sqlserver/Automation/KillSpid.sql") { 
  $line | Add-Content "q.sql" 
  }
$cmd = "/opt/mssql-tools/bin/" + $conn + " -i q.sql -o res.log"

இது, நீங்கள் புரிந்து கொண்டபடி, ஏற்கனவே யுனிக்ஸ் பதிப்பிலிருந்து ஒரு சோதனை.

கோப்புகளைப் பதிவேற்றுகிறது

விண்டோஸ் பதிப்பில், எந்தவொரு செயலும் தணிக்கையுடன் சேர்ந்தது: நாங்கள் sqlcmd ஐ இயக்கினோம், வெளியீட்டு கோப்பில் சில வகையான முறைகேடுகளைப் பெற்றோம், இந்த கோப்பை தணிக்கைத் தட்டில் இணைத்தோம். அதிர்ஷ்டவசமாக, SQL சேவையகம் ஜென்கின்ஸ் போன்ற அதே சேவையகத்தில் வேலை செய்தது, இது இப்படி செய்யப்பட்டது:

CREATE procedure AuditUpload
  @id int, @filename varchar(256)
as
  set nocount on
  declare @sql varchar(max)

  CREATE TABLE #multi (filer NVARCHAR(MAX))
  set @sql='BULK INSERT #multi FROM '''+@filename
    +''' WITH (ROWTERMINATOR = '' '',CODEPAGE = ''ACP'')'
  exec (@sql)
  select @sql=filer from #multi
  update JenkinsAudit set multiliner=@sql where ID=@id
  return

எனவே, நாம் BCP கோப்பை முழுவதுமாக விழுங்கி, தணிக்கை அட்டவணையின் nvarchar(max) புலத்தில் தள்ளுவோம். நிச்சயமாக, இந்த முழு அமைப்பும் உடைந்து போனது, ஏனென்றால் SQL சேவையகத்திற்கு பதிலாக நான் RDS ஐப் பெற்றேன், மேலும் ஒரு கோப்பில் பிரத்யேக பூட்டை எடுக்கும் முயற்சியின் காரணமாக UNC வழியாக BULK INSERT வேலை செய்யாது, மேலும் RDS உடன் இது பொதுவாக அழிந்துவிடும். ஆரம்பம். எனவே கணினி வடிவமைப்பை மாற்ற முடிவு செய்தேன், தணிக்கை வரியை வரி மூலம் சேமித்து வைத்தேன்:

CREATE TABLE AuditOut (
  ID int NULL,
  TextLine nvarchar(max) NULL,
  n int IDENTITY(1,1) PRIMARY KEY
  )

இந்த அட்டவணையில் இப்படி எழுதுங்கள்:

function WriteAudit([string]$Filename, [string]$ConnStr, 
     [string]$Tabname, [string]$Jobname)
{
  # get $lastid of the last execution  -- проскипано для статьи
	
  #create grid and populate it with data from file
  $audit =  Get-Content $Filename
  $DT = new-object Data.DataTable   

  $COL1 =  new-object Data.DataColumn; 
  $COL1.ColumnName = "ID"; 
  $COL1.DataType =  [System.Type]::GetType("System.Int32") 

  $COL2 =  new-object Data.DataColumn; 
  $COL2.ColumnName = "TextLine"; 
  $COL2.DataType =  [System.Type]::GetType("System.String") 
  
  $DT.Columns.Add($COL1) 
  $DT.Columns.Add($COL2) 
  foreach ($line in $audit) 
    { 
    $DR = $dt.NewRow()   
    $DR.Item("ID") = $lastid
    $DR.Item("TextLine") = $line
    $DT.Rows.Add($DR)   
    } 

  # write it to table
  $conn=new-object System.Data.SqlClient.SQLConnection 
  $conn.ConnectionString = $ConnStr
  $conn.Open() 
  $bulkCopy = new-object ("Data.SqlClient.SqlBulkCopy") $ConnStr
  $bulkCopy.DestinationTableName = $Tabname 
  $bulkCopy.BatchSize = 50000
  $bulkCopy.BulkCopyTimeout = 0
  $bulkCopy.WriteToServer($DT) 
  $conn.Close() 
  }  

உள்ளடக்கத்தைத் தேர்ந்தெடுக்க, நீங்கள் ஐடி மூலம் தேர்ந்தெடுக்க வேண்டும், n (அடையாளம்) வரிசையில் தேர்ந்தெடுக்கவும்.

அடுத்த கட்டுரையில், இவை அனைத்தும் ஜென்கின்ஸ் உடன் எவ்வாறு தொடர்பு கொள்கின்றன என்பதைப் பற்றி மேலும் விரிவாகப் பேசுவேன்.

ஆதாரம்: www.habr.com

DDoS பாதுகாப்பு, VPS VDS சர்வர்கள் கொண்ட தளங்களுக்கு நம்பகமான ஹோஸ்டிங் வாங்கவும் 🔥 DDoS பாதுகாப்புடன் கூடிய நம்பகமான இணையதள ஹோஸ்டிங், VPS, VDS சர்வர்களை வாங்குங்கள் | ProHoster