月度归档:2013 年四月

恢复MySQL主从同步

今天发现两台机器上的mysql主从复制不能用了。估计原因是从上写入了数据,导致有重复主键。处理如下:

1.先将所有有对这个库有写入或修改动作的脚本;

2.备份从库,复制主库,拷贝主库到从库上,并恢复;

/usr/local/mysql/bin/mysqldump -hlocalhost -uroot -ppwd123  keyword_storage > keyword_storage_20130427.sql
source /home/nengzuo/keyword_storage_20130427.sql

3.删除从库上的relay日志;

4.重新更改主从配置,主要修改日志文件和位置;

change master to master_host='192.168.0.164', master_user='kwmgr', master_password='pwd123', master_log_file='mysql-bin.000087', master_log_pos=324352;

5.重新启动slave;

start slave

6.测试是否正确

show slave status\G

c#提升用户权限

private void btnElevate_Click(object sender, EventArgs e)
{
    // Elevate the process if it is not run as administrator.
    if (!IsRunAsAdmin())
    {
        // Launch itself as administrator
        ProcessStartInfo proc = new ProcessStartInfo();
        proc.UseShellExecute = true;
        proc.WorkingDirectory = Environment.CurrentDirectory;
        proc.FileName = Application.ExecutablePath;
        proc.Verb = "runas";
     
        try
        {
            Process.Start(proc);
        }
        catch
        {
            // The user refused to allow privileges elevation.
            // Do nothing and return directly ...
            return;
        }
     
        Application.Exit();  // Quit itself
    }
    else
    {
        MessageBox.Show("The process is running as administrator", "UAC");
    }
}

判断自己是否管理员

/// <summary>
/// The function checks whether the current process is run as administrator.
/// In other words, it dictates whether the primary access token of the 
/// process belongs to user account that is a member of the local 
/// Administrators group and it is elevated.
/// </summary>
/// <returns>
/// Returns true if the primary access token of the process belongs to user 
/// account that is a member of the local Administrators group and it is 
/// elevated. Returns false if the token does not.
/// </returns>
internal bool IsRunAsAdmin()
{
    WindowsIdentity id = WindowsIdentity.GetCurrent();
    WindowsPrincipal principal = new WindowsPrincipal(id);
    return principal.IsInRole(WindowsBuiltInRole.Administrator);
}

判断用户是否在管理员组

/// <summary>
/// The function checks whether the primary access token of the process belongs 
/// to user account that is a member of the local Administrators group, even if 
/// it currently is not elevated.
/// </summary>
/// <returns>
/// Returns true if the primary access token of the process belongs to user 
/// account that is a member of the local Administrators group. Returns false 
/// if the token does not.
/// </returns>
/// <exception cref="System.ComponentModel.Win32Exception">
/// When any native Windows API call fails, the function throws a Win32Exception 
/// with the last error code.
/// </exception>
internal bool IsUserInAdminGroup()
{
    bool fInAdminGroup = false;
    SafeTokenHandle hToken = null;
    SafeTokenHandle hTokenToCheck = null;
    IntPtr pElevationType = IntPtr.Zero;
    IntPtr pLinkedToken = IntPtr.Zero;
    int cbSize = 0;
   
    try
    {
        // Open the access token of the current process for query and duplicate.
        if (!NativeMethod.OpenProcessToken(Process.GetCurrentProcess().Handle,
            NativeMethod.TOKEN_QUERY | NativeMethod.TOKEN_DUPLICATE, out hToken))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
   
        // Determine whether system is running Windows Vista or later operating 
        // systems (major version >= 6) because they support linked tokens, but 
        // previous versions (major version < 6) do not.
        if (Environment.OSVersion.Version.Major >= 6)
        {
            // Running Windows Vista or later (major version >= 6). 
            // Determine token type: limited, elevated, or default. 
   
            // Allocate a buffer for the elevation type information.
            cbSize = sizeof(TOKEN_ELEVATION_TYPE);
            pElevationType = Marshal.AllocHGlobal(cbSize);
            if (pElevationType == IntPtr.Zero)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
   
            // Retrieve token elevation type information.
            if (!NativeMethod.GetTokenInformation(hToken, 
                TOKEN_INFORMATION_CLASS.TokenElevationType, pElevationType,
                cbSize, out cbSize))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
   
            // Marshal the TOKEN_ELEVATION_TYPE enum from native to .NET.
            TOKEN_ELEVATION_TYPE elevType = (TOKEN_ELEVATION_TYPE)
                Marshal.ReadInt32(pElevationType);
   
            // If limited, get the linked elevated token for further check.
            if (elevType == TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited)
            {
                // Allocate a buffer for the linked token.
                cbSize = IntPtr.Size;
                pLinkedToken = Marshal.AllocHGlobal(cbSize);
                if (pLinkedToken == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
   
                // Get the linked token.
                if (!NativeMethod.GetTokenInformation(hToken,
                    TOKEN_INFORMATION_CLASS.TokenLinkedToken, pLinkedToken,
                    cbSize, out cbSize))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
   
                // Marshal the linked token value from native to .NET.
                IntPtr hLinkedToken = Marshal.ReadIntPtr(pLinkedToken);
                hTokenToCheck = new SafeTokenHandle(hLinkedToken);
            }
        }
           
        // CheckTokenMembership requires an impersonation token. If we just got 
        // a linked token, it already is an impersonation token.  If we did not 
        // get a linked token, duplicate the original into an impersonation 
        // token for CheckTokenMembership.
        if (hTokenToCheck == null)
        {
            if (!NativeMethod.DuplicateToken(hToken,
                SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
                out hTokenToCheck))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
        }
   
        // Check if the token to be checked contains admin SID.
        WindowsIdentity id = new WindowsIdentity(hTokenToCheck.DangerousGetHandle());
        WindowsPrincipal principal = new WindowsPrincipal(id);
        fInAdminGroup = principal.IsInRole(WindowsBuiltInRole.Administrator);
    }
    finally
    {
        // Centralized cleanup for all allocated resources. 
        if (hToken != null)
        {
            hToken.Close();
            hToken = null;
        }
        if (hTokenToCheck != null)
        {
            hTokenToCheck.Close();
            hTokenToCheck = null;
        }
        if (pElevationType != IntPtr.Zero)
        {
            Marshal.FreeHGlobal(pElevationType);
            pElevationType = IntPtr.Zero;
        }
        if (pLinkedToken != IntPtr.Zero)
        {
            Marshal.FreeHGlobal(pLinkedToken);
            pLinkedToken = IntPtr.Zero;
        }
    }
   
    return fInAdminGroup;
}

判断进程是否已经被提升

/// <summary>
/// The function gets the elevation information of the current process. It 
/// dictates whether the process is elevated or not. Token elevation is only 
/// available on Windows Vista and newer operating systems, thus 
/// IsProcessElevated throws a C++ exception if it is called on systems prior 
/// to Windows Vista. It is not appropriate to use this function to determine 
/// whether a process is run as administartor.
/// </summary>
/// <returns>
/// Returns true if the process is elevated. Returns false if it is not.
/// </returns>
/// <exception cref="System.ComponentModel.Win32Exception">
/// When any native Windows API call fails, the function throws a Win32Exception 
/// with the last error code.
/// </exception>
/// <remarks>
/// TOKEN_INFORMATION_CLASS provides TokenElevationType to check the elevation 
/// type (TokenElevationTypeDefault / TokenElevationTypeLimited / 
/// TokenElevationTypeFull) of the process. It is different from TokenElevation 
/// in that, when UAC is turned off, elevation type always returns 
/// TokenElevationTypeDefault even though the process is elevated (Integrity 
/// Level == High). In other words, it is not safe to say if the process is 
/// elevated based on elevation type. Instead, we should use TokenElevation. 
/// </remarks>
internal bool IsProcessElevated()
{
    bool fIsElevated = false;
    SafeTokenHandle hToken = null;
    int cbTokenElevation = 0;
    IntPtr pTokenElevation = IntPtr.Zero;
  
    try
    {
        // Open the access token of the current process with TOKEN_QUERY.
        if (!NativeMethod.OpenProcessToken(Process.GetCurrentProcess().Handle,
            NativeMethod.TOKEN_QUERY, out hToken))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
  
        // Allocate a buffer for the elevation information.
        cbTokenElevation = Marshal.SizeOf(typeof(TOKEN_ELEVATION));
        pTokenElevation = Marshal.AllocHGlobal(cbTokenElevation);
        if (pTokenElevation == IntPtr.Zero)
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
  
        // Retrieve token elevation information.
        if (!NativeMethod.GetTokenInformation(hToken, 
            TOKEN_INFORMATION_CLASS.TokenElevation, pTokenElevation,
            cbTokenElevation, out cbTokenElevation))
        {
            // When the process is run on operating systems prior to Windows 
            // Vista, GetTokenInformation returns false with the error code 
            // ERROR_INVALID_PARAMETER because TokenElevation is not supported 
            // on those operating systems.
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
  
        // Marshal the TOKEN_ELEVATION struct from native to .NET object.
        TOKEN_ELEVATION elevation = (TOKEN_ELEVATION)Marshal.PtrToStructure(
            pTokenElevation, typeof(TOKEN_ELEVATION));
  
        // TOKEN_ELEVATION.TokenIsElevated is a non-zero value if the token 
        // has elevated privileges; otherwise, a zero value.
        fIsElevated = (elevation.TokenIsElevated != 0);
    }
    finally
    {
        // Centralized cleanup for all allocated resources. 
        if (hToken != null)
        {
            hToken.Close();
            hToken = null;
        }
        if (pTokenElevation != IntPtr.Zero)
        {
            Marshal.FreeHGlobal(pTokenElevation);
            pTokenElevation = IntPtr.Zero;
            cbTokenElevation = 0;
        }
    }
  
    return fIsElevated;
}

sphinx实现模糊查询

一、需求

1.假设能做网有两个子域名:blog.nengzuo.com, www.nengzuo.com,  我需要在搜索.nengzuo.com时,能把包含两个子域名和自己的都搜出来。

2.因为量比较大(亿级),所以要求尽量使索引速度最快,占用资源最少。

二、思路

A.首先,因为域名中含有字符'-'和'.',所以需要在charset_table中把这俩字符加进去。

    charset_table = U+FF10..U+FF19->0..9, 0..9, U+FF41..U+FF5A->a..z, U+FF21..U+FF3A->a..z,\
A..Z->a..z, a..z,U+002e,U+002d

其次,如果想实现模糊查询,需要将中辍值设为>0,并且不能指定infix_field。

    morphology = none
    # 索引词最小长度 
    min_word_len = 0
    #enable_star = 1
    #prefix_fields = domain
    #infix_fields = domain
    #ignore_chars = -   
    # 数据编码(设置成utf8才能索引中文) 
    charset_type = utf-8
    charset_table = U+FF10..U+FF19->0..9, 0..9, U+FF41..U+FF5A->a..z, U+FF21..U+FF3A->a..z,\
A..Z->a..z, a..z,U+002e,U+002d
    # 最小索引前缀长度 
    min_prefix_len = 0
    # 最小索引中缀长度 
    min_infix_len = 1
    # 对于非字母型数据的长度切割(for CJK indexing) 
    ngram_len = 1
    # 对否对去除用户输入查询内容的html标签 
    html_strip = 0

min_infix_len的值可以设置大一点,但无论怎样配置,消耗的资源(包括时间和空间)都是几十倍的增涨。实在令人难以承受。


B.不用中辍,不用charset_table,配置如下:

index page_fact1
{
    # 索引源声明 
    source = src_page_fact1
    #source = src_page_fact2
    #source = src_page_fact3
 
    # 索引文件的存放位置 
    path = /data/sphinx-chinese/data_search_1/page_fact1
    # 文件存储模式(默认为extern) 
    docinfo = extern
    # 缓存数据内存锁定 
    mlock = 0
    # 马氏形态学(对中文无效) 
    morphology = none
    # 索引词最小长度 
    min_word_len = 0
    enable_star = 1
    #prefix_fields = domain
    #ignore_chars = -   
    # 数据编码(设置成utf8才能索引中文) 
    charset_type = utf-8
    # 最小索引前缀长度 
    min_prefix_len = 0
    # 最小索引中缀长度 
    min_infix_len = 0
    # 对于非字母型数据的长度切割(for CJK indexing) 
    ngram_len = 1
    # 对否对去除用户输入查询内容的html标签 
    html_strip = 0
}

最关键的地方是要在查询的时候的要以句子表达式来约束主域名,即把原来查询条件用引号括起来:


mysql> select * from page_fact1 where match('".nengzuo.com"');