PostgreSQL Saatlik Yedekleme Script’i

Projemizde birden fazla Postgresql veritabanı bulunmakta.  Hepsinde de anlık değişiklikler olabiliyor. Sistemsel olarak yedeklemeler mevcut fakat .SQL uzantılı yedeğimiz bulunmamakta. Çünkü bir tablo veya bir satır içerik / veri için tüm sistemi geri döndürmek oldukça mantıksız duruyor.

Daha öncesinde MYSQL için yapmış olduğum yedekleme BASH SCRIPT’ini POSTGRESQL için uyarladım ve çalışır hale getirdim. Database boyutu düşük olduğu için 24 saatlik yedekleme şuanda gayet uygun. Database boyutunu ve server disk kapasitesini düşünerekten geçmişe dönük yedekleri silmeyi unutmayın. Canınız yanar 🙂

Okumaya devam et “PostgreSQL Saatlik Yedekleme Script’i”

Linux Servis Takip & Autostart

Linux ortamlarında birşeyler koşturuyorsanız bazen servisleriniz size naz yapıyor olabilir. Bu nazlı haller geldiğinde ise servisleri restart edip işimize devam ederiz. Genellikle neden nazlandığını bulamayız. Çok derin inceleme ve araştırma gerekebilir. 🙂

Bunun için servisi takip edip durma durumuna göre hızlıca restart eden scriptler mevcut tabiki. Stackoverflow’da bulduğum örneklerden bir tanesi;

#!/bin/bash
service=SERVICE_NAME

if (( $(ps -ef | grep -v grep | grep $service | wc -l) > 0 ))
then
	echo "$service is running!"
else
	/etc/init.d/$service restart
fi

SERVICE_NAME yazısını servisinizin adı olarak değiştirmeniz yeterli. Örnek olarak “httpd” olabilir. Bash script’i kaydedip CRON olarak eklemeniz ve isteğe göre zaman tanımı yapmanız yeterli. Ben genellikle dakikalık periyotları kullanıyorum.

* * * * * sudo sh /home/service_check.sh > /dev/null 2>&1

Linux dağıtımıza göre yetkilendirme işlemleri gerekebilir.  Bu işlemin arkasına web servis veya mail ortamı bağlayıp kendinize de bildirimler gönderebilirsiniz.

Linux CentOS Geçmiş Silme / History Clear

Linux kullanıcılarının çoğu bilir. Hatta HACKER muhabbetlerinde de sürekli geçer.
Asla ayak izlerini belli etme”.
Hacker işlemlerinden çok bir sunucuda konfigürasyon sırasında girilen şifreler olabilir veya yapılan işlemler, adımlar, sql sorguları vb. linux terminal üzerinde yön tuşlarından Yukarı veya Aşağı tuşları ile neler yapılmış neler edilmiş görebilirsiniz. Hatta kullanmış olduğunuz Linux dağıtımına göre history komutu ile listeleme yapabilir, farklı dosyaya çıktı dahi alabilirsiniz.

Hacker muhabbetlerinden ziyade yapılan işin güvenliğini düşünecek olursak – ki bu da hacker muhabbetine dönebilir – geçmişinizi muhakkak kontrol edin, temiz tutun. Bunun için en basit ve birinci adımlardan birisi aşağıdaki komutlardır diyebilirim. Terminalinizden logout / çıkış yapmadan önce komutları uygulayınız..

cat /dev/null > ~/.bash_history && history -c
cat /dev/null > ~/.mysql_history && history -c

 

Tabiki daha detaylı işlemler mevcut. Aklıma gelmişken sizinle paylaşayım dedim. Bunu yapınca hacker vs. olunmuyor onu da söylim 🙂

Veeam Backup & Replication Windows Server Hostname Değiştirme ( Değiştirmeme )

Ufak bir anı paylaşımı daha.
Sanallaştırma teknolojileriden VMware kullanmaktayız. Sanal sistemlerimizi yedeklemek amacıyla da Veeam Backup & Replication kullanıyoruz. Kurulu olan sanal Windows server üzerinde de HOSTNAME’i ( Sunucu / Bilgisayar adı ) ilk kurulum sırasında default olarak bırakmışız. Bu böyle kalmasın diyip değiştirdiğimizde ise Veeam Backup çalışmadı. Değişiklik yapmadan önce yedeklerınızı almanızı tavsiye ederim. Yedekleme tarafı önemli olduğu çözümü bulamadan eski hostname’i geri aldık. Farklı bir sistem üzerinde kurup çözümünü test edeceğim.  Başarılı olursa paylaşacağım. Muhakkak birileri yapmıştır diye düşünüyorum.
Şuna benzer bir hata alıyorsunuz;
“could not connect to server: Connection refused Is the server running on host ‘localhost’ “
Şimdilik demem şudur ki değiştirirseniz problemlerin ardı arkası kesilmiyor. Ya da sisteminiz zaten eski ise yenisini kurup eski konfigürasyonu yenisine taşıyın. 🙂 Ya da değiştirmeyin. 🙂
Sağlıcakla..

Windows Server Arayüz Giderse Geri Getirme

Windows bir sunucunuz var ve ayarları ile oynarken ( Genellikle server ayarları ile oynamanızı tavisye etmem. Fakat en iyi tecrübe şeklidir 🙂 ) yeniden başlatma isteği gelir ve ne olduğunu okumadan EVET’e basarsanız neler mi olabilir. Birçok şey olabilir. Gün içerisinde yaşadığım bir olayı sizlerle paylaşmak istiyorum.

Kenarda köşede kalmış sadece bazı işlemleri yapmak için kullandığım bir Windows sunucu vardı. RDP ( Remote Desktop Protocol | Uzak Masa Üstü Bağlantısı ) olarak kullanıyordum. Üzerinde test için IIS ( Internet Information Services ) kuruluydu. Windows özelliklerinden IIS’i kaldırırken çok fazla dikkat etmeden kaldır sihirbazını kullanarak kaldırığımda sistem benden yeniden başlatma istedi. Ne mi oldu ? Aşağıdaki gibi birşey oldu.

windows-server-cli

Okumaya devam et “Windows Server Arayüz Giderse Geri Getirme”

CodeIgniter WebServis Veritabanı Hatalarını Yakalamak

Codeigniter ile yürüttüğümüz birkaç web servisimiz mevcut. Bu servislerimiz arka planda olduğu için genellikle veritabanı sorguları ve çalışan sorgulardaki hataları yakalayamıyoruz. Bunun için system/database/DB_driver.php dosyasında birazcık oynayacağız.

display_error fonksiyonunda hataları gösteren yere farklı bir domain/sub domain altındaki servisimize gönderiyoruz. Bu servis üzerinde ise gelen bilgileri alıp Mail olarak yazılım ekibimize gönderiyoruz. Böylece bir hata olduğunda yakalama şansımız yüksek oluyor.

Mail göndermek yerine farklı senaryolarda yapılabilir. Örneğin telegramdan kendinize bildirim gönderebilirsiniz. Başka bir veritabanına hataları yazabilirsiniz. SMS hadi attırabilirsiniz. Monitoring yazılımınız ile entegre edebilirsiniz. Bildirim servisini aktif etmek tamamıyla sizin ihtiyaçlarınıza kalmış bir durum.

Okumaya devam et “CodeIgniter WebServis Veritabanı Hatalarını Yakalamak”

PHP CodeIgniter İle İmage Cache Yapımı

Hemen hemen herkesin ihtiyacıdır diye düşünüyorum. İmage Cache. Genellikle bir tane PROXY URL oluşturup dosyaya ait cache hali varsa onu çekeriz yoksa cache’leyip cache halini çekeriz. Fakat bu durum sistemde dosyalarınızın gelmesini yavaşlatabilir.

Hali hazırsa orjinal dosyalarınızın bulunduğu bir klasör altında image dosyalarınız var ise aşağıdaki paylaşmış olduğum örnekteki gibi bir yöntem ile dosyaların boyutlandırılmasını orantılı bir şekilde yapabilirsiniz.

Bir önceki yazımda “get_dir_contents” fonksiyonunu paylaşmıştım. Bir dizin altındaki tüm dosyaları getirmek için kullanıyoruz.

$list = get_dir_contents( '/var/www/html/cron/orj_images' );

// hangi boyutlarda oluşturacağımızı belirtiyoruz.
$arr[] = array( 32, 32 );
$arr[] = array( 50, 50 );
$arr[] = array( 64, 64 );
$arr[] = array( 70, 70 );
$arr[] = array( 80, 80 );
$arr[] = array( 90, 90 );
$arr[] = array( 100, 100 );
$arr[] = array( 120, 120 );
$arr[] = array( 150, 150 );
$arr[] = array( 160, 200 );
$arr[] = array( 200, 200 );
$arr[] = array( 300, 300 );
$arr[] = array( 200, 256 );
$arr[] = array( 256, 256 );
$arr[] = array( 500, 500 );
$arr[] = array( 512, 512 );
$arr[] = array( 640, 640 );
$arr[] = array( 1024, 1024 );
$i = 0;
// listemizde döngüye girip image_lib kütüphanesi ile işlemleri başlatıyoruz.
foreach( $list as $key => $value )
{
	if( !file_exists( $value ) )
		continue;
	if( is_dir( $value ) )
		continue;
	
	$this->load->library( 'image_lib' );
	// her bir dosya için boyutlandırma dizisine göre ayrı ayrı işlem yaptırıyoruz.
	foreach ( $arr as $k => $v )
	{
		$ext = pathinfo( $value );

		$new_file = $ext[ 'dirname' ].'/'.$ext[ 'filename' ].'-'.$v[ 0 ].'x'.$v[ 1 ].'.'.$ext[ 'extension' ];				
		$old_file = str_replace( '/var/www/html/cron/orj_images', '/var/www/html/cron/chache_images', $new_file );			
		
		if( file_exists( $old_file ) )
			continue;
		// kaynak dosyamnız $value değişkenindedir.
		$config = array(
			'image_library' => 'gd2',
			'source_image' => $value,
			'new_image' => $old_file,
			'maintain_ratio' => TRUE,
			'create_thumb' => TRUE,
			'thumb_marker' => '',
			'width' => $v[ 0 ],
			'height' => $v[ 1 ]
		);

		$this->image_lib->initialize( $config );
		$this->image_lib->resize();
		$this->image_lib->clear();
		echo $old_file."\n";
	}
}

Yeni dosya ekleme işlemlerinde upload sırasında bu boyutlar otomatik olarak cachleniyor. Sistemde orjinal dosya direkt olarak kullanılmıyor.

Bu kod parçasını CRON üzerinden bağladığımız için dosyaları mümkün olduğunda güncel kalmasını sağlıyoruz.

Not : “Yapı Codeigniter framework’ü üzerinden örneklendirilmiştir. Sisteminize uygulamadan önce test etmenizi tavsiye ederim.”

 

MSSQL CSV Formatında Saatlik Yedek Aldırma İşlemi

Bir projemizde kullanılan MSSQL Server Database sistemi için saatlik yedeklemelere ihtiyaç duyduk.

C#.Net ortamında çalışmaktadır. Otomatik olarak her saat yedek alabilmesi için ise outputtaki .exe dosyasını “Zamanlanmış Görevlere ( Task Scheduler )” zamanlanmış görev olarak çalıştırıyoruz. Veritabanındaki tabloları listeleyip tüm dataları dump ediyoruz. CSV formatında dosyaya yazıyoruz ve sıkıştırma işlemini gerçekleştiriyoruz. Böylece disk kaybı yaşamıyoruz.

Birden fazla Database mevcut ise önce onları çekip ayrı ayrı da çalıştırabilirsiniz. Geliştirilip farklı varsyonlarda eklenebilir. FTP olarak farklı bir alanada yükleme yapılabilir. Bu sistemde şuanda tüm dosyalar tutuluyor. Manuel olarak silmek yerine birkaç saat öncesine ait klasörleri silebilirsiniz. Diskten kazanmış olursunuz.

Program parçasını full olarak paylaşıyorum;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.IO;
using System.Data;
using System.Text;
using System.IO.Compression;

namespace WindowsFormsApp7
{
	static class Program
	{
		/// 
<summary>
		/// The main entry point for the application.
		/// </summary>

		/// 
		private static string directoryPath = @"c:\temp";
		[STAThread]

		static void Main()
		{
			Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);

			SqlConnection sqlCon = new SqlConnection("Data Source=IP;Initial Catalog=DATABASE;User ID=USERNAME;Password=PASSWORD;MultipleActiveResultSets=True;");
			sqlCon.Open();
			string sql = "SELECT sc.name + '.' + ta.name TableName ,SUM(pa.rows) RowCnt FROM sys.tables ta INNER JOIN sys.partitions pa ON pa.OBJECT_ID = ta.OBJECT_ID INNER JOIN sys.schemas sc ON ta.schema_id = sc.schema_id WHERE ta.is_ms_shipped = 0 AND pa.index_id IN(1,0) GROUP BY sc.name,ta.name having SUM(pa.rows) > 0 and sc.name +'.'+ ta.name IN ( 'dbo.EFAT_ZARF' ) ORDER BY SUM(pa.rows) DESC";
			SqlCommand com = new SqlCommand(sql, sqlCon);
			SqlDataReader read = com.ExecuteReader();

			//string dirname = "DOSYAYOLU" + (DateTime.Now).ToString("yyyy-MM-dd");
			string dirname = "C:/SQL_BACKUP/" + (DateTime.Now).ToString("yyyy-MM-dd");
			CreateIfMissing(dirname);

			dirname += "/" + (DateTime.Now).ToString("HH");

			CreateIfMissing(dirname);
			string rar_dir = @"" + dirname;
			string rar_path = @"" + dirname + ".zip";
			List<string> filess = new List<string>();
			while (read.Read())
			{
				string fileName = dirname + "/" + read.GetValue(0) + ".csv";
				filess.Add(fileName);
				SqlCommand sqlCmd = new SqlCommand();
				sqlCmd.CommandText = "SELECT * FROM " + read.GetValue(0) + " with (NOLOCK)";
				sqlCmd.Connection = sqlCon;

				sqlCmd.Dispose();
				using (var CommandText = new SqlCommand("SELECT * FROM " + read.GetValue(0) + " with (NOLOCK)"))
				using (var reader = sqlCmd.ExecuteReader())
				//using (var outFile = File.CreateText(fileName))
				using (StreamWriter outFile = new StreamWriter(File.Open(fileName, FileMode.Create), Encoding.UTF8))
				{
					string[] columnNames = GetColumnNames(reader).ToArray();
					int numFields = columnNames.Length;
					outFile.WriteLine(string.Join(",", columnNames));
					if (reader.HasRows)
					{
						while (reader.Read())
						{
							string[] columnValues =
							Enumerable.Range(0, numFields)
							.Select(i => get_string( reader.GetValue(i) ))
							.Select(field => string.Concat("\"", field.Replace("\"", "\"\""), "\""))
							.ToArray();
							outFile.WriteLine(string.Join(",", columnValues));
						}
					}
				}

			}
			sqlCon.Close();
			directoryPath = rar_dir;
			DirectoryInfo directorySelected = new DirectoryInfo(directoryPath);
			Compress(directorySelected);
			foreach (var item in filess)
			{
				if (File.Exists(item))
				File.Delete(item);
			}
			
		}

		public static string get_string( object ss )
		{
			if (!(ss.ToString().Length > 2))
			return ss.ToString();
			if (ss.ToString().Substring(0, 2) == "0x")
			return System.Text.Encoding.UTF8.GetString((Byte[])ss);
			return ss.ToString();
		}

		public static string Base64Encode(string plainText)
		{
			var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
			return System.Convert.ToBase64String(plainTextBytes);
		}

		static void CreateIfMissing(string path)
		{
			bool folderExists = Directory.Exists(path);
			if (!folderExists)
			Directory.CreateDirectory(path);
		}

		static IEnumerable<string> GetColumnNames(IDataReader reader)
		{
			foreach (DataRow row in reader.GetSchemaTable().Rows)
			{
				yield return (string)row["ColumnName"];
			}
		}

		public static void Compress(DirectoryInfo directorySelected)
		{
			foreach (FileInfo fileToCompress in directorySelected.GetFiles())
			{
				using (FileStream originalFileStream = fileToCompress.OpenRead())
				{
					if ((File.GetAttributes(fileToCompress.FullName) & FileAttributes.Hidden) != FileAttributes.Hidden & fileToCompress.Extension != ".gz")
					{
						using (FileStream compressedFileStream = File.Create(fileToCompress.FullName + ".gz"))
						{
							using (GZipStream compressionStream = new GZipStream(compressedFileStream,CompressionMode.Compress))
							{
								originalFileStream.CopyTo(compressionStream);
							}
						}
						//FileInfo info = new FileInfo(directoryPath + "\\" + fileToCompress.Name + ".gz");
						//Console.WriteLine("Compressed {0} from {1} to {2} bytes.",fileToCompress.Name, fileToCompress.Length.ToString(), info.Length.ToString());
					}
				}
			}
		}
	}
}

 

 

 

Centos 7 Üzerinde Vesta Panel PHP 7 Upgrade Etme

Projelerimizin FTP / HOST hesaplarını daha rahat yönebilmek amacıyla VESTA Panel kullanmaktayız. Vesta gayet hoş, basit, hafif ve çok fazla uğraştırmadan sunucu üzerine kurulum yapıp kullanabilirsiniz.
Vesta Panel kurulumu için — > https://vestacp.com/install/  
İhtiyaçlarınıza göre vesta seçeneklerini seçerek kurulumu Console üzerinden yapabilirsiniz.

Şuanda Vesta kurulumu yapıldığında PHP sürümü 5.6 olarak gelmekte. Bu sürümün desteği bittiği için ve birçok hazır framework sitelerde hata göstermektedir ( WordPress, opencart vs. ) . Yakında bunu düzeltirler sanırım. PHP 7 versiyonu daha sağlıklı, hızlı ve stabil çalışmasından dolayı genel sistemlerimizi de güncellemekteyiz.

Güncelleme işlemi yaparken aşağıdaki adımları sırayla uygulayabilirsiniz.

  • wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
  • wget http://rpms.remirepo.net/enterprise/remi-release-7.rpm
  • rpm -Uvh remi-release-7.rpm epel-release-latest-7.noarch.rpm
  • yum install yum-utils
  • yum-config-manager –enable remi-php72
  • yum-config-manager –disable remi-php56
  • yum-config-manager –disable remi-php70
  • yum-config-manager –disable remi-php71
  • yum update -y
  • php -v

Yukarıdaki işlemleri CLI / Console üzerinden yapmanız gerekir.
Hatasız update ler dilerim. 🙂

Kaynak

Linux WGET ile Dosya Çekme

Sistem yedeklemelerinde olduğum NAS ( Network Area Stroage ) mevcuttur. Sistem tarafında, hosting, sunucu gibi yazılım işleri ile koşturan hemen hemen herkes NAS kullanmaktadır. Farklı yedekleme sistemleri de mevcuttur fakat NAS güzeldir. 🙂

NAS üzerinde dosyaları çekmek istediğimize problemler yaşıyorduk. Çünkü bazı klasörlerin içerisinde dosya sayıları fazla olduğu için açılmıyor veya kullanmış olduğumuz FTP programları hataya düşüyordu.

Yapılması gereken ise dosyaları belirli aralıklarla çekip local tarafa aktarmaktı. İnternet üzerinde araştırmalar yaparken stackoverflow’da bulduğum yöntem bizi kurtardı. Biz dosya halinde değil KLASÖR halinde çekmek istediğimizden yöntem hızı gibi yetişti.

Detaya girmeden komutu paylaşacağım. Komut;

wget -r -nH --cut-dirs=5 -nc ftp://user:pass@server//absolute/path/to/directory

Linux üzerinde hangi dizindeyseniz wget komutu oraya çeker.  Kullanım yukarıdaki gibidir.

–cut-dirs=5 –> bu her seferinde 5 işlem yap diyebilmek için. Böylece listeleme ile uğraşmadığından FTP programları gibi patlamıyoruz.

Kaynak yazıya buradan ulaşabilirsiniz..

Ara ara dediğim gibi başka canlar yanmasın.. 🙂